home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
vbdatabs
/
strdbw.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-28
|
127KB
|
4,207 lines
// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- //
// C++ Source Code File Name: strdbw.cpp
// Compiler Used: MSVC40, HP CPP 10.24
// Produced By: Doug Gaer
// File Creation Date: 12/16/1997
// Date Last Modified: 03/29/1999
// Copyright (c) 1997 Douglas M. Gaer
// ----------------------------------------------------------- //
// ------------- Program Description and Details ------------- //
// ----------------------------------------------------------- //
/*
The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
All those who put this code or its derivatives in a commercial
product MUST mention this copyright in their documentation for
users of the products in which this code or its derivative
classes are used. Otherwise, you have the freedom to redistribute
verbatim copies of this source code, adapt it to your specific
needs, or improve the code and release your improvements to the
public provided that the modified files carry prominent notices
stating that you changed the files and the date of any change.
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
CORRECTION.
The string database is a general-purpose object-oriented
database. This version is designed to work with the wxWindow
GUI library version 1.68
- Modify "dbconfig.h" file to customize the database
- Modify "dbvers.h" file to uniquely identify the database
- Modify "dbtcfg.h" file to customize this program
- Modify "version.h" file to report changes and fixes
*/
// ----------------------------------------------------------- //
#include <stdlib.h> // Needed for getenv under HPUX CPP
#include "timer.h"
#include "strdbw.h"
#include "strutil.h"
#include "asprint.h"
#include "vbdstats.h"
#include "btwalker.h"
// This struct was added to read Variable Block Headers because
// the Status member of VBHeader struct in the vbdfile.h file
// caused a syntax error when compiling this program under HPUX
// CPP version 1024.
struct VBlockHeader // (V)ariable (B)lock (H)eader
{
UINT32 CkWord; // (C)heck (W)ord for file integrity checks (4 bytes)
UINT32 Length; // Length of this block including VB header (4 bytes)
UINT32 VBStatus; // Status of dynamic data stored in VB (4 byte)
FAU NextDeletedVB; // Pointer to next deleted VB (4 bytes)
};
// (V)ariable (B)lock (D)atabse components
static POD *DB; // Global database pointer
StrDB *astrdb = 0; // Global data buffer used to add objects
StrDB *cstrdb = 0; // Global data buffer used to change objects
StrDB *dstrdb = 0; // Global data buffer used to display objects
const char *WildCard = "*"; // Used for wild card searches
// Output limit per string for ASCII printing
const int StringOffset = 15; // Output limit per string
// Declare frame, subframe and menu objects
MyFrame *frame = 0;
wxMenuBar *menu_bar = 0;
wxFrame *APanelFrame = 0;
wxFrame *CPanelFrame = 0;
wxFrame *DPanelFrame = 0;
#ifdef __USE_MSW_PRINTING__
wxDialogBox *wxPageDialog = 0; // MSW page setup dialog box
MSWPrintingParameters MSWPrnPars;
MSWPrintingParameters *MSWPrintSetup = &MSWPrnPars;
const int mswpDocNameLen = 255;
char mswpDocumentName[mswpDocNameLen];
#endif // __USE_MSW_PRINTING__
// Variable used to print display list objects
int print_list = 0;
int num_objects = 0;
int displaying_list = 0;
// Font, Pen, and Cursor objects
wxFont *labelFont = 0;
wxFont *itemFont = 0;
wxFont *textWindowFont = 0;
// wxWindows control objects
wxButton *btn_add_add = 0; // Object Add Panel Add button
wxButton *btn_add_can = 0; // Object Add Panel Cancel button
wxButton *btn_add_close = 0; // Object Add Panel Close button
wxButton *btn_add_revert = 0; // Object Add Panel Revert button
wxButton *btn_ch_sh = 0; // Object Change Panel Search button
wxButton *btn_ch_cm = 0; // Object Change Panel Commit button
wxButton *btn_ch_can = 0; // Object Change Panel Cancel button
wxButton *btn_ch_close = 0; // Object Change Panel Close button
wxButton *btn_ch_revert = 0; // Object Change Panel Revert button
wxButton *btn_ds_nx = 0; // Object Display Panel Next button
wxButton *btn_ds_prev = 0; // Object Display Panel Previous button
wxButton *btn_ds_ch = 0; // Object Display Panel Change button
wxButton *btn_ds_rm = 0; // Object Display Panel Remove button
wxButton *btn_ds_close = 0; // Object Display Panel Close button
#ifdef __USE_MSW_PRINTING__
wxButton *btn_pdb_close = 0; // MSW page setup dialog Close button
wxButton *btn_pdb_cancel = 0; // MSW page setup dialog Accept button
wxButton *btn_pdb_accept = 0; // MSW page setup dialog Accept button
wxButton *btn_pdb_default = 0; // MSW page setup dialog Default button
wxSlider *LppSlider = 0; // Lines per page slider
wxSlider *CellSlider = 0; // Cell width slider
wxSlider *FsSlider = 0; // Font size slider
wxSlider *LRMSlider = 0; // Left and right margin slider
wxChoice *OrientationChoice = 0; // Orientation choice box
char *OrChoiceStrings[2] = {
"Landscape",
"Portrait"
};
wxChoice *FontChoice = 0; // Font family choice box
char *FontChoiceStrings[6] = {
"Swiss", // wxSWISS
"Roman", // wxROMAN
"Decorative", // wxDECORATIVE
"Modern", // wxMODERN
"Script", // wxSCRIPT
"System" // wxDEFAULT
};
#endif // __USE_MSW_PRINTING__
// This statement initializes the whole application and calls OnInit
MyApp myApp;
// A macro needed for some compilers (AIX) that need 'main' to be defined
// in the application itself.
IMPLEMENT_WXWIN_MAIN
// `Main program' equivalent, creating windows and returning main app frame
wxFrame *MyApp::OnInit(void)
{
// Create the main frame window
frame = new MyFrame(NULL, (char *)ProgramName, 50, 50, 400, 300);
// Give this frame a status line
frame->CreateStatusLine(1);
// Give it an icon
#ifdef wx_msw
frame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
frame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
// File menu
wxMenu *file_menu = new wxMenu;
file_menu->Append(FILE_VBDSTATS, "VBD file Stats",
"Display VBD file statistics");
file_menu->AppendSeparator();
file_menu->Append(FILE_EXPORT, "Export","Export database to ASCII file");
file_menu->Append(FILE_IMPORT, "Import", "Import ASCII file into database");
file_menu->Append(FILE_TEMPLATE, "Create Template",
"Create an ASCII template for import file");
file_menu->AppendSeparator();
file_menu->Append(FILE_BACKUP, "Backup",
"Backup the database to another file");
file_menu->Append(FILE_MERGE, "Merge",
"Merge the contents of another database file");
file_menu->AppendSeparator();
file_menu->Append(FILE_COMPARE_INDEX, "Compare Index File",
"Compare the index file to the database file");
file_menu->Append(FILE_REBUILD_INDEX, "Rebuild Index File",
"Rebuild the index file for this database");
file_menu->AppendSeparator();
file_menu->Append(FILE_QUIT, "E&xit","Exit this program");
// Edit menu
wxMenu *edit_menu = new wxMenu;
edit_menu->Append(EDIT_CUT, "Cut\tCtrl+X", "Cut text and copy to clipboard");
edit_menu->AppendSeparator();
edit_menu->Append(EDIT_COPY, "Copy\tCtrl+C", "Copy text to clipboard");
edit_menu->AppendSeparator();
edit_menu->Append(EDIT_PASTE, "Paste\tCtrl+V", "Paste text from clipboard");
// Database menu
wxMenu *db_menu = new wxMenu;
db_menu->Append(DB_DISPLAY, "&Display", "Display all objects one a time");
db_menu->AppendSeparator();
db_menu->Append(DB_ADD, "&Add", "Add objects to the database");
db_menu->AppendSeparator();
db_menu->Append(DB_CHANGE, "&Change", "Change an object in the database");
db_menu->AppendSeparator();
db_menu->Append(DB_REMOVE, "&Remove", "Remove an object from the database");
// Find menu
wxMenu *find_menu = new wxMenu;
find_menu->AppendSeparator();
const char *Prompt = "Find by ";
UString s(Prompt); int PromptLen = strlen(Prompt); int StringLen = 0;
if(KeyName != 0) {
s = s + KeyName; StringLen = strlen(KeyName);
find_menu->Append(FIND_BYKEYNAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M2Name != 0) {
s = s + M2Name; StringLen = strlen(M2Name);
find_menu->Append(FIND_BYM2NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M3Name != 0) {
s = s + M3Name; StringLen = strlen(M3Name);
find_menu->Append(FIND_BYM3NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M4Name != 0) {
s = s + M4Name; StringLen = strlen(M4Name);
find_menu->Append(FIND_BYM4NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M5Name != 0) {
s = s + M5Name; StringLen = strlen(M5Name);
find_menu->Append(FIND_BYM5NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M6Name != 0) {
s = s + M6Name; StringLen = strlen(M6Name);
find_menu->Append(FIND_BYM6NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M7Name != 0) {
s = s + M7Name; StringLen = strlen(M7Name);
find_menu->Append(FIND_BYM7NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(M8Name != 0) {
s = s + M8Name; StringLen = strlen(M8Name);
find_menu->Append(FIND_BYM8NAME, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
if(Comments != 0) {
s = s + Comments; StringLen = strlen(Comments);
find_menu->Append(FIND_BYCOMMENTS, s.c_str(), s.c_str());
find_menu->AppendSeparator();
s.DeleteAt(PromptLen, StringLen);
}
// Print menu
wxMenu *print_menu = new wxMenu;
#ifdef __USE_MSW_PRINTING__
print_menu->Append(WXPRINT_PRINT, "Print...",
"Print to the selected printer");
print_menu->Append(WXPRINT_PRINTER_SETUP, "Printer Setup...",
"Configure the seleted printer");
print_menu->Append(WXPRINT_PAGE_SETUP, "Page Setup...",
"Set the page parameters before printing");
print_menu->Append(WXPRINT_PREVIEW, "Print Preview",
"Preview before printing");
print_menu->AppendSeparator();
#endif // __USE_MSW_PRINTING__
print_menu->Append(PRINT_POSTSCRIPT, "Print to PostScript file",
"Print database to a PostScript file");
print_menu->AppendSeparator();
print_menu->Append(PRINT_HTML, "Print to HTML file",
"Print database to an HTML file");
print_menu->AppendSeparator();
print_menu->Append(PRINT_ASCIIALL, "Print to text file 80 cols",
"Print to text file (abbreviated, 80 cols)");
print_menu->Append(PRINT_ASCIILONG, "Print to text file 132 cols",
"Print to text file (full listing, 132 cols)");
print_menu->AppendSeparator();
print_menu->Append(PRINT_ASCIIOBJECT, "Print object to text file",
"Print a single object to a text file");
// View menu
wxMenu *view_menu = new wxMenu;
view_menu->Append(VIEW_CLEAR, "&Clear Window", "Clear this text window");
// Help menu
wxMenu *help_menu = new wxMenu;
help_menu->Append(HELP_ABOUT, "&About", "Info about this program");
help_menu->AppendSeparator();
help_menu->Append(HELP_USERLEVEL, "Access Rights",
"Display your user access rights");
// Make all the menu bars
menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, "&File");
menu_bar->Append(edit_menu, "&Edit");
menu_bar->Append(db_menu, "Data&base");
menu_bar->Append(find_menu, "F&ind");
menu_bar->Append(print_menu, "&Print");
menu_bar->Append(view_menu, "&View");
menu_bar->Append(help_menu, "&Help");
frame->SetMenuBar(menu_bar);
// Associate the menu bar with the frame
frame->SetMenuBar(menu_bar);
// Create a text window in the main frame
frame->textWin = new MyTextWindow(frame, 0, 250, 400, 250,
wxNATIVE_IMPL);
frame->textWin->DragAcceptFiles(TRUE);
// *********************************************************** //
// Object Add Panel Code Starts Here
// *********************************************************** //
frame->addText = new MyText; // Init MyText Class pointer
APanelFrame = new wxFrame(NULL, "Adding Object", 0, 0, 370, 370);
// Panel fonts
labelFont = new wxFont(12, wxSWISS, wxNORMAL, wxBOLD);
itemFont = new wxFont(11, wxSWISS, wxNORMAL, wxBOLD);
// Give it an icon
#ifdef wx_msw
APanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
APanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int apfwidth, apfheight;
APanelFrame->GetClientSize(&apfwidth, &apfheight);
// Make a panel in the subframe
frame->apanel = new wxPanel(APanelFrame, 0, 0,
apfwidth, apfheight);
frame->apanel->SetLabelPosition(wxVERTICAL);
frame->apanel->SetLabelFont(labelFont);
frame->apanel->SetButtonFont(itemFont);
frame->apanel->SetFont(itemFont);
// Needed to line up first addText box under motif
frame->apanel->NewLine();
if(KeyName != 0)
frame->addText->key = new wxText(frame->apanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->apanel->NewLine();
if(M2Name != 0)
frame->addText->m2 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
if(M3Name != 0)
frame->addText->m3 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->apanel->NewLine();
if(M4Name != 0)
frame->addText->m4 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 150, -1);
if(M5Name != 0)
frame->addText->m5 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M5Name, "", -1, -1, 150, -1);
frame->apanel->NewLine();
if(M6Name != 0)
frame->addText->m6 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M6Name, "", -1, -1, 150, -1);
if(M7Name != 0)
frame->addText->m7 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M7Name, "", -1, -1, 150, -1);
frame->apanel->NewLine();
if(M8Name != 0)
frame->addText->m8 = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)M8Name, "", -1, -1, 150, -1);
if(Comments != 0)
frame->addText->cmt = new wxText(frame->apanel, (wxFunction)&text_proc,
(char *)Comments, "", -1, -1, 150, -1);
frame->apanel->NewLine();
btn_add_add = new wxButton(frame->apanel, (wxFunction)&AddBtnProc, "Add");
btn_add_add->SetClientData((char*)ADD_BUTTON_ADD); // ID the button
btn_add_can = new wxButton(frame->apanel,(wxFunction)&AddBtnProc, "Cancel");
btn_add_can->SetClientData((char*)ADD_BUTTON_CANCEL); // ID the button
btn_add_close = new wxButton(frame->apanel, (wxFunction)&AddBtnProc,
"Close");
btn_add_close->SetClientData((char*)ADD_BUTTON_CLOSE); // ID the button
btn_add_revert = new wxButton(frame->apanel, (wxFunction)&AddBtnProc,
"Revert");
btn_add_revert->SetClientData((char*)ADD_BUTTON_REVERT); // ID the button
// *********************************************************** //
// Object Add Panel Code Ends Here
// *********************************************************** //
// *********************************************************** //
// Object Change Panel Code Starts Here
// *********************************************************** //
frame->changeText = new MyText; // Init MyText Class pointer
CPanelFrame = new wxFrame(NULL, "Changing Object", 0, 0, 400, 390);
// Give it an icon
#ifdef wx_msw
CPanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
CPanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int cpfwidth, cpfheight;
CPanelFrame->GetClientSize(&cpfwidth, &cpfheight);
// Make a panel in the subframe
frame->cpanel = new wxPanel(CPanelFrame, 0, 0,
cpfwidth, cpfheight);
frame->cpanel->SetLabelPosition(wxVERTICAL);
frame->cpanel->SetLabelFont(labelFont);
frame->cpanel->SetButtonFont(itemFont);
frame->cpanel->SetFont(itemFont);
// Needed to line up first panel with the others under motif
frame->cpanel->NewLine();
UString cmesg("Enter the ");
cmesg = cmesg + KeyName + " and click on Search.";
wxMessage *message = new wxMessage(frame->cpanel, cmesg.c_str());
frame->cpanel->NewLine();
if(KeyName != 0)
frame->changeText->key = new wxText(frame->cpanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->cpanel->NewLine();
if(M2Name != 0)
frame->changeText->m2 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
if(M3Name != 0)
frame->changeText->m3 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
if(M4Name != 0)
frame->changeText->m4 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 150, -1);
if(M5Name != 0)
frame->changeText->m5 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M5Name, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
if(M6Name != 0)
frame->changeText->m6 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M6Name, "", -1, -1, 150, -1);
if(M7Name != 0)
frame->changeText->m7 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M7Name, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
if(M8Name != 0)
frame->changeText->m8 = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)M8Name, "", -1, -1, 150, -1);
if(Comments != 0)
frame->changeText->cmt = new wxText(frame->cpanel, (wxFunction)&text_proc,
(char *)Comments, "", -1, -1, 150, -1);
frame->cpanel->NewLine();
btn_ch_sh = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Search");
btn_ch_sh->SetClientData((char*)CHANGE_BUTTON_SH); // ID the button
btn_ch_cm = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Commit");
btn_ch_cm->SetClientData((char*)CHANGE_BUTTON_CM); // ID the button
btn_ch_cm->Enable(0);
btn_ch_can = new wxButton(frame->cpanel,(wxFunction)&ChBtnProc, "Cancel");
btn_ch_can->SetClientData((char*)CHANGE_BUTTON_CANCEL); // ID the button
btn_ch_close = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc, "Close");
btn_ch_close->SetClientData((char*)CHANGE_BUTTON_CLOSE); // ID the button
btn_ch_revert = new wxButton(frame->cpanel, (wxFunction)&ChBtnProc,
"Revert");
btn_ch_revert->SetClientData((char*)CHANGE_BUTTON_REVERT); // ID the button
// *********************************************************** //
// Object Change Panel Code Ends Here
// *********************************************************** //
// *********************************************************** //
// Object Display Panel Code Starts Here
// *********************************************************** //
frame->displayText = new MyText; // Init MyText Class pointer
DPanelFrame = new wxFrame(NULL, "Displaying Objects", 0, 0,
370, 370);
// Give it an icon
#ifdef wx_msw
DPanelFrame->SetIcon(new wxIcon("vbdbase"));
#endif
#ifdef wx_x
DPanelFrame->SetIcon(new wxIcon("vbdbase.xbm"));
#endif
int dpfwidth, dpfheight;
DPanelFrame->GetClientSize(&dpfwidth, &dpfheight);
// Make a panel in the subframe
frame->dpanel = new wxPanel(DPanelFrame, 0, 0,
dpfwidth, dpfheight);
frame->dpanel->SetLabelPosition(wxVERTICAL);
frame->dpanel->SetLabelFont(labelFont);
frame->dpanel->SetButtonFont(itemFont);
frame->dpanel->SetFont(itemFont);
// Needed to line up first addText box under motif
frame->dpanel->NewLine();
if(KeyName != 0) {
frame->displayText->key = new wxText(frame->dpanel, NULL,
(char *)KeyName, "",-1,-1,150,-1);
frame->displayText->key->SetEditable(FALSE);
}
frame->dpanel->NewLine();
if(M2Name != 0) {
frame->displayText->m2 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M2Name, "", -1, -1, 150, -1);
frame->displayText->m2->SetEditable(FALSE);
}
if(M3Name != 0) {
frame->displayText->m3 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M3Name, "", -1, -1, 150, -1);
frame->displayText->m3->SetEditable(FALSE);
}
frame->dpanel->NewLine();
if(M4Name != 0) {
frame->displayText->m4 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M4Name, "", -1, -1, 150, -1);
frame->displayText->m4->SetEditable(FALSE);
}
if(M5Name != 0) {
frame->displayText->m5 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M5Name, "", -1, -1, 150, -1);
frame->displayText->m5->SetEditable(FALSE);
}
frame->dpanel->NewLine();
if(M6Name != 0) {
frame->displayText->m6 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M6Name, "", -1, -1, 150, -1);
frame->displayText->m6->SetEditable(FALSE);
}
if(M7Name != 0) {
frame->displayText->m7 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M7Name, "", -1, -1, 150, -1);
frame->displayText->m7->SetEditable(FALSE);
}
frame->dpanel->NewLine();
if(M8Name != 0) {
frame->displayText->m8 = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)M8Name, "", -1, -1, 150, -1);
frame->displayText->m8->SetEditable(FALSE);
}
if(Comments != 0) {
frame->displayText->cmt = new wxText(frame->dpanel, (wxFunction)&text_proc,
(char *)Comments, "", -1, -1, 150, -1);
frame->displayText->cmt->SetEditable(FALSE);
}
frame->dpanel->NewLine();
frame->dpanel->NewLine();
btn_ds_nx = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Next");
btn_ds_nx->SetClientData((char*)DISPLAY_BUTTON_NX); // ID the button
btn_ds_prev = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Prior");
btn_ds_prev->SetClientData((char*)DISPLAY_BUTTON_PREV); // ID the button
btn_ds_ch = new wxButton(frame->dpanel,(wxFunction)&DsBtnProc, "Change");
btn_ds_ch->SetClientData((char*)DISPLAY_BUTTON_CHANGE); // ID the button
btn_ds_close = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Close");
btn_ds_close->SetClientData((char*)DISPLAY_BUTTON_CLOSE); // ID the button
btn_ds_rm = new wxButton(frame->dpanel, (wxFunction)&DsBtnProc, "Remove");
btn_ds_rm->SetClientData((char*)DISPLAY_BUTTON_REMOVE); // ID the button
// *********************************************************** //
// Object Display Panel Code Ends Here
// *********************************************************** //
// Show the frames
frame->Show(TRUE);
APanelFrame->Show(FALSE);
CPanelFrame->Show(FALSE);
displaying_list = 0;
DPanelFrame->Show(FALSE);
// Vaiable Block Database components
char *FileName = 0;
char *CurrentCfgFile = 0;
char *CfgFile = 0;
Config *CfgData = new Config;
char *AdminUser = 0;
const char *DefaultWelcomeMesg = "welcome.txt";
char *WelcomeMesgFile = 0;
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
int mswp_lines_per_page = 0;
int mswp_cell_length = 0;
int mswp_font_size = 0;
int mswp_left_margin = 0;
char *mswp_orientation = 0;
char *mswp_doc_name = 0;
char *mswp_font = 0;
#endif // __USE_MSW_PRINTING__
// Look for CfgFile name in environment
if((CurrentCfgFile = getenv(EnvSetting)) == 0)
CfgFile = (char *)DefaultCfgFile;
else
CfgFile = CurrentCfgFile;
// Use default file name if no file is specifed on command line
if(argc < 2) {
int FileStatus = CfgData->Load((char *)CfgFile);
if(!FileStatus) {
Error->Message("Cannot locate any database files!\n",
"Defaulting to: ", DefaultDBFileName);
FileName = (char *)DefaultDBFileName;
WelcomeMesgFile = (char *)DefaultWelcomeMesg;
}
else {
// *********************************************************** //
// Add all startup config file entries here
// *********************************************************** //
FileName = CfgData->GetStrValue("DBFileName");
AdminUser = CfgData->GetStrValue("AdminUser");
WelcomeMesgFile = CfgData->GetStrValue("WelcomeMessageFile");
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
mswp_lines_per_page = CfgData->GetIntValue("mswpLinesPerPage");
mswp_cell_length = CfgData->GetIntValue("mswpCellLength");
mswp_font_size = CfgData->GetIntValue("mswpFontSize");
mswp_left_margin = CfgData->GetIntValue("mswpLeftMargin");
mswp_orientation = CfgData->GetStrValue("mswpOrientation");
mswp_font = CfgData->GetStrValue("mswpFont");
mswp_doc_name = CfgData->GetStrValue("mswpDocumentName");
#endif // __USE_MSW_PRINTING__
// *********************************************************** //
if(!FileName) {
UString comp("\nDefaulting to: ");
comp = comp + DefaultDBFileName;
Error->Message("DBFileName section missing in config file:\n",
CfgFile, comp.c_str());
FileName = (char *)DefaultDBFileName;
}
}
}
else {
FileName = argv[1];
}
if(!AdminUser) {
AdminRights = 0;
frame->SetStatusText((char *)ProgramName);
}
else {
int result = strcmp(AdminUser, "TRUE");
if(result == 0) {
AdminRights = 1;
frame->SetStatusText("ADMIN USER");
}
else {
AdminRights = 0;
frame->SetStatusText((char *)ProgramName);
}
}
if(!WelcomeMesgFile)
WelcomeMesgFile = (char *)DefaultWelcomeMesg;
#ifdef __USE_MSW_PRINTING__
// Default values for wxWindows MSW Printing
if(mswp_lines_per_page > 0) {
MSWPrintSetup->lines_per_page = mswp_lines_per_page;
MSWPrintSetup->prev_lines_per_page = mswp_lines_per_page;
MSWPrintSetup->default_lines_per_page = mswp_lines_per_page;
}
if(mswp_cell_length > 0) {
MSWPrintSetup->cell_length = mswp_cell_length;
MSWPrintSetup->prev_cell_length = mswp_cell_length;
MSWPrintSetup->default_cell_length = mswp_cell_length;
}
if(mswp_font_size > 0) {
MSWPrintSetup->font_size = mswp_font_size;
MSWPrintSetup->prev_font_size = mswp_font_size;
MSWPrintSetup->default_font_size = mswp_font_size;
}
if(mswp_left_margin > 0) {
MSWPrintSetup->lr_margin = mswp_left_margin;
MSWPrintSetup->prev_lr_margin = mswp_left_margin;
MSWPrintSetup->default_lr_margin = mswp_left_margin;
}
if(mswp_orientation != 0) {
if(strcmp(mswp_orientation, "PORTRAIT") == 0) {
MSWPrintSetup->orientation = 1;
MSWPrintSetup->prev_orientation = 1;
MSWPrintSetup->default_orientation = 1;
}
if(strcmp(mswp_orientation, "LANDSCAPE") == 0) {
MSWPrintSetup->orientation = 0;
MSWPrintSetup->prev_orientation = 0;
MSWPrintSetup->default_orientation = 0;
}
}
if(mswp_font != 0) {
if(strcmp(mswp_font, "SWISS") == 0) {
MSWPrintSetup->font = 0;
MSWPrintSetup->prev_font = 0;
MSWPrintSetup->default_font = 0;
}
if(strcmp(mswp_font, "ROMAN") == 0) {
MSWPrintSetup->font = 1;
MSWPrintSetup->prev_font = 1;
MSWPrintSetup->default_font = 1;
}
if(strcmp(mswp_font, "DECORATIVE") == 0) {
MSWPrintSetup->font = 2;
MSWPrintSetup->prev_font = 2;
MSWPrintSetup->default_font = 2;
}
if(strcmp(mswp_font, "MODERN") == 0) {
MSWPrintSetup->font = 3;
MSWPrintSetup->prev_font = 3;
MSWPrintSetup->default_font = 3;
}
if(strcmp(mswp_font, "SCRIPT") == 0) {
MSWPrintSetup->font = 4;
MSWPrintSetup->prev_font = 4;
MSWPrintSetup->default_font = 4;
}
if(strcmp(mswp_font, "SYSTEM") == 0) {
MSWPrintSetup->font = 5;
MSWPrintSetup->prev_font = 5;
MSWPrintSetup->default_font = 5;
}
}
for(int i = 0; i < mswpDocNameLen; i++) mswpDocumentName[i] = 0;
if(mswp_doc_name != 0)
strcpy(mswpDocumentName, mswp_doc_name);
else
strcpy(mswpDocumentName, ProgramName);
#endif // __USE_MSW_PRINTING__
CfgData->UnLoad(); // Unload the Config file from memory
// Initialize global database pointer
// NOTE: Index file and data file will share the same file name
// with different file extensions. The data file will have a
// .pod extension and the index file will have a .btx extension.
if(AdminRights == 1)
DB = new POD(FileName, RWMode, 1, CacheSize);
else
DB = new POD(FileName, ROMode, 1, CacheSize);
astrdb = new StrDB(DB); // Initialize global buffer pointer
cstrdb = new StrDB(DB); // Initialize global buffer pointer
dstrdb = new StrDB(DB); // Initialize global buffer pointer
// Display the welcome message if it exists
frame->textWin->LoadFile(WelcomeMesgFile);
// Return the main frame window
return frame;
}
MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
wxFrame(frame, title, x, y, w, h)
{
textWin = 0;
apanel = 0;
cpanel = 0;
dpanel = 0;
addText = 0;
changeText = 0;
}
Bool MyFrame::OnClose(void)
// Define the behaviour for the frame closing
{
// Close sub-frames
if(APanelFrame) {
APanelFrame->Close(TRUE);
delete APanelFrame;
}
if(CPanelFrame) {
CPanelFrame->Close(TRUE);
delete CPanelFrame;
}
if(DPanelFrame) {
DPanelFrame->Close(TRUE);
delete DPanelFrame;
}
// Close main frame
Show(FALSE);
// Clean up Variable Block Database objects
if(DB) delete DB;
if(astrdb) delete astrdb;
if(cstrdb) delete cstrdb;
if(dstrdb) delete dstrdb;
return TRUE;
}
void MyFrame::OnMenuCommand(int id)
// Intercept menu commands
{
switch (id) {
case FILE_QUIT:
if (OnClose()) delete this;
break;
case FILE_VBDSTATS:
textWin->Clear();
*(textWin) << "----- Database file statistics -----" << "\n";
VBDStats(textWin, DB->OpenDatabase());
*(textWin) << "----- Index file statistics -----" << "\n";
VBDStats(textWin, DB->OpenIndexFile());
break;
case FILE_EXPORT:
ExportToASCII(*textWin);
break;
case FILE_IMPORT:
ImportFromASCII(*textWin);
break;
case FILE_BACKUP:
BackUp(*textWin);
break;
case FILE_MERGE:
Merge(*textWin);
break;
case FILE_TEMPLATE:
CreateTemplate(*textWin);
break;
case FILE_COMPARE_INDEX:
CompareIndexFile(*textWin);
break;
case FILE_REBUILD_INDEX:
RebuildIndexFile(*textWin);
break;
case EDIT_CUT:
textWin->Cut();
break;
case EDIT_COPY:
textWin->Copy();
break;
case EDIT_PASTE:
textWin->Paste();
break;
case DB_ADD:
Add(*textWin);
break;
case DB_CHANGE:
Change(*textWin);
break;
case DB_REMOVE:
Remove(*textWin);
break;
case DB_DISPLAY:
DisplayDB(*textWin);
break;
case FIND_BYKEYNAME:
FindBy(*textWin, KeyName, KEYMEMBER);
break;
case FIND_BYM2NAME:
FindBy(*textWin, M2Name, M2NAME);
break;
case FIND_BYM3NAME:
FindBy(*textWin, M3Name, M3NAME);
break;
case FIND_BYM4NAME:
FindBy(*textWin, M4Name, M4NAME);
break;
case FIND_BYM5NAME:
FindBy(*textWin, M5Name, M5NAME);
break;
case FIND_BYM6NAME:
FindBy(*textWin, M6Name, M6NAME);
break;
case FIND_BYM7NAME:
FindBy(*textWin, M7Name, M7NAME);
break;
case FIND_BYM8NAME:
FindBy(*textWin, M8Name, M8NAME);
break;
case FIND_BYCOMMENTS:
FindBy(*textWin, Comments, COMMENTS);
break;
#ifdef __USE_MSW_PRINTING__
case WXPRINT_PRINT:
{
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else {
print_list = 0;
}
wxPrinter printer(&printData);
wStrDBPrint printout((char *)ProgramName);
if (!printer.Print(this, &printout, TRUE))
wxMessageBox("The document was not printed.",
"Printing", wxOK);
break;
}
case WXPRINT_PREVIEW:
{
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
if(displaying_list) {
int yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxYES) print_list = 1; else print_list = 0;
}
else {
print_list = 0;
}
// Pass two printout objects: for preview, and possible printing.
wxPrintPreview *preview = \
new wxPrintPreview(new wStrDBPrint((char *)ProgramName),
new wStrDBPrint((char *)ProgramName),
&printData);
if (!preview->Ok()) {
delete preview;
wxMessageBox("There was a problem previewing.",
"Previewing", wxOK);
return;
}
wxPreviewFrame *frame = new wxPreviewFrame(preview,
this,
(char *)ProgramName,
100, 100, 600, 650);
frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(TRUE);
break;
}
case WXPRINT_PRINTER_SETUP:
{
#ifdef wx_msw
myApp.SetPrintMode(wxPRINT_WINDOWS);
#else
// Allow MSW style printing under UNIX
myApp.SetPrintMode(wxPRINT_POSTSCRIPT);
#endif
wxPrintData printData;
if(MSWPrintSetup->orientation == 0)
printData.SetOrientation(wxLANDSCAPE);
else
printData.SetOrientation(wxPORTRAIT);
wxPrintDialog printerDialog(this, &printData);
printerDialog.GetPrintData().SetSetupDialog(TRUE);
printerDialog.Show(TRUE);
break;
}
case WXPRINT_PAGE_SETUP:
{
int xpos=300; int ypos=300; int width=300;
#ifdef wx_msw
int height=250;
#else
// Allow MSW style printing under UNIX
int height=350;
#endif
wxPageDialog = new wxDialogBox(this, "Page Setup", TRUE,
xpos, ypos, width, height,
wxDEFAULT_DIALOG_STYLE,
"Page Setup");
wxPageDialog->Centre();
wxPageDialog->NewLine();
LppSlider = new wxSlider(wxPageDialog, NULL, "Lines Per Page",
MSWPrintSetup->lines_per_page,
1, 200, 200);
wxPageDialog->NewLine();
CellSlider = new wxSlider(wxPageDialog, NULL, "Cell Length",
MSWPrintSetup->cell_length,
1, 50, 150);
wxPageDialog->NewLine();
FsSlider = new wxSlider(wxPageDialog, NULL, "Font Size ",
MSWPrintSetup->font_size,
1, 50, 150);
wxPageDialog->NewLine();
LRMSlider = new wxSlider(wxPageDialog, NULL, "Left Margin",
MSWPrintSetup->lr_margin,
1, 20, 150);
wxPageDialog->NewLine();
wxMessage *om = new wxMessage(wxPageDialog,
"The Orientation must match the Printer Setup");
wxPageDialog->NewLine();
OrientationChoice = new wxChoice(wxPageDialog, NULL, "Orientation",
-1, -1, -1, -1, 2, OrChoiceStrings);
OrientationChoice->SetSelection(MSWPrintSetup->orientation);
wxPageDialog->NewLine();
FontChoice = new wxChoice(wxPageDialog, NULL, "Font",
-1, -1, -1, -1, 6, FontChoiceStrings);
FontChoice->SetSelection(MSWPrintSetup->font);
wxPageDialog->NewLine();
btn_pdb_close = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Close", 10, -1, -1, -1);
btn_pdb_close->SetClientData((char*)PAGE_DIALOG_BUTTON_CLOSE);
btn_pdb_accept = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Accept", 60, -1, -1, -1);
btn_pdb_accept->SetClientData((char*)PAGE_DIALOG_BUTTON_ACCEPT);
btn_pdb_cancel = new wxButton(wxPageDialog, (wxFunction)&page_btn_proc,
"Cancel", 118, -1, -1, -1);
btn_pdb_cancel->SetClientData((char*)PAGE_DIALOG_BUTTON_CANCEL);
btn_pdb_default = new wxButton(wxPageDialog,
(wxFunction)&page_btn_proc,
"Default", 175, -1, -1, -1);
btn_pdb_default->SetClientData((char*)PAGE_DIALOG_BUTTON_DEFAULT);
wxPageDialog->Show(TRUE);
break;
}
#endif // __USE_MSW_PRINTING__
case PRINT_POSTSCRIPT:
PostScriptPrint(*textWin);
break;
case PRINT_HTML:
HTMLPrint(*textWin);
break;
case PRINT_ASCIIALL:
ASCIIPrintAll(*textWin);
break;
case PRINT_ASCIILONG:
ASCIIPrintAllLong(*textWin);
break;
case PRINT_ASCIIOBJECT:
ASCIIPrintObject(*textWin);
break;
case VIEW_CLEAR:
Clear(*textWin);
break;
case HELP_ABOUT: {
char *s = VerNumber();
UString mesg(ProgramName);
mesg = mesg + "\nVersion Number " + s;
wxMessageBox(mesg.c_str(), "About", wxOK|wxCENTRE);
break;
}
case HELP_USERLEVEL: {
UString mesg;
if(AdminRights) {
mesg = mesg + "You have Admin User Privileges\n" + \
"As defined in the " + DefaultCfgFile + " config file\n";
wxMessageBox(mesg.c_str(), "Access Level", wxOK|wxCENTRE);
}
else {
mesg = mesg + "You do not have Admin User Privileges\n" + \
"As defined in the " + DefaultCfgFile + " config file\n";
wxMessageBox(mesg.c_str(), "Access Level", wxOK|wxCENTRE);
}
break;
}
}
}
void MyTextWindow::OnChar(wxKeyEvent& event)
{
if(event.keyCode == CONTROL('x')) {
Cut();
frame->SetStatusText("Cut text and copied to clipboard");
}
if(event.keyCode == CONTROL('c')) {
Copy();
frame->SetStatusText("Copied text from clipboard");
}
if(event.keyCode == CONTROL('v')) {
Paste();
frame->SetStatusText("Pasted text from clipboard");
}
wxTextWindow::OnChar(event); // Process the default behavior
}
void MyFrame::OnSize(int w, int h)
{
wxFrame::OnSize(w, h);
}
MyText::MyText(wxPanel *parent, wxFunction func, char *label,
char *value, int x, int y, int width, int height ,
long style, char *name) :
wxText(parent, func, label, value,x, y, width, height , style, name)
{
key = m2 = m3 = m4 = m5 = m6 = m7 = m8 = cmt = 0;
}
MyText::~MyText()
{
if(key) delete key;
if(m2) delete m2;
if(m3) delete m3;
if(m4) delete m4;
if(m5) delete m5;
if(m6) delete m6;
if(m7) delete m7;
if(m8) delete m8;
if(cmt) delete cmt;
}
void Clear(MyTextWindow& textWin)
{
textWin.Clear();
}
char *VerNumber()
// Version number for this windows program. Edit the version.h
// file to change this program's version number
{
char buf[10];
sprintf(buf, "%.3f", VersionNumber);
int len = strlen(buf);
char *s = new char[len+1];
s[len+1] = '\0';
strcpy(s, buf);
return s;
}
void text_proc(wxText &but, wxCommandEvent &event)
{
// Nothing to do
}
void AddBtnProc(wxButton& but, wxCommandEvent& event)
{
UString sbuf; // Character string input buffer
long tag = (long)but.GetClientData() ;
if(tag == ADD_BUTTON_ADD) {
UString key_name;
UString m2_name;
UString m3_name;
UString m4_name;
UString m5_name;
UString m6_name;
UString m7_name;
UString m8_name;
UString cmts;
if(KeyName != 0) key_name = frame->addText->key->GetValue();
if(M2Name != 0) m2_name = frame->addText->m2->GetValue();
if(M3Name != 0) m3_name = frame->addText->m3->GetValue();
if(M4Name != 0) m4_name = frame->addText->m4->GetValue();
if(M5Name != 0) m5_name = frame->addText->m5->GetValue();
if(M6Name != 0) m6_name = frame->addText->m6->GetValue();
if(M7Name != 0) m7_name = frame->addText->m7->GetValue();
if(M8Name != 0) m8_name = frame->addText->m8->GetValue();
if(Comments != 0) cmts = frame->addText->cmt->GetValue();
// Remove any leading space from the key name entry
int offset = key_name.Find(" ");
if(offset == 0) key_name.DeleteAt(offset, 1);
if(key_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
StrDB strdb(DB);
strdb.SetKM(key_name);
FAU addr = strdb.FindObject();
if(addr) {
sbuf = sbuf + "An Entry for " + key_name + " already exists!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
if(KeyName != 0) astrdb->SetKM(key_name.c_str());
if(M2Name != 0) astrdb->SetM2(m2_name.c_str());
if(M3Name != 0) astrdb->SetM3(m3_name.c_str());
if(M4Name != 0) astrdb->SetM4(m4_name.c_str());
if(M5Name != 0) astrdb->SetM5(m5_name.c_str());
if(M6Name != 0) astrdb->SetM6(m6_name.c_str());
if(M7Name != 0) astrdb->SetM7(m7_name.c_str());
if(M8Name != 0) astrdb->SetM8(m8_name.c_str());
if(Comments != 0) astrdb->SetCM(cmts.c_str());
addr = astrdb->AddObject(0); // Write the object to the file
if(!addr) {
sbuf = sbuf + "Could not add Entry for " + astrdb->GetKM();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
return;
}
sbuf = sbuf + "Added Entry for " + astrdb->GetKM();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
ClearAddPanel();
if(displaying_list) {
InMemCopy inmemcopy(astrdb->GetKM(), astrdb->ObjectAddress(),
astrdb->GetClassID());
dllist->StoreNode(inmemcopy);
}
}
if(tag == ADD_BUTTON_CANCEL) {
ClearAddPanel();
return;
}
if(tag == ADD_BUTTON_CLOSE) {
APanelFrame->Show(FALSE);
return;
}
if(tag == ADD_BUTTON_REVERT) {
if(KeyName != 0)
if(astrdb->GetKM())
frame->addText->key->SetValue(astrdb->GetKM());
if(M2Name != 0)
if(astrdb->GetM2())
frame->addText->m2->SetValue(astrdb->GetM2());
if(M3Name != 0)
if(astrdb->GetM3())
frame->addText->m3->SetValue(astrdb->GetM3());
if(M4Name != 0)
if(astrdb->GetM4())
frame->addText->m4->SetValue(astrdb->GetM4());
if(M5Name != 0)
if(astrdb->GetM5())
frame->addText->m5->SetValue(astrdb->GetM5());
if(M6Name != 0)
if(astrdb->GetM6())
frame->addText->m6->SetValue(astrdb->GetM6());
if(M7Name != 0)
if(astrdb->GetM7())
frame->addText->m7->SetValue(astrdb->GetM7());
if(M8Name != 0)
if(astrdb->GetM8())
frame->addText->m8->SetValue(astrdb->GetM8());
if(Comments != 0)
if(astrdb->GetCM())
frame->addText->cmt->SetValue(astrdb->GetCM());
return;
}
}
void ClearAddPanel()
{
if(KeyName != 0) frame->addText->key->SetValue("");
if(M2Name != 0) frame->addText->m2->SetValue("");
if(M3Name != 0) frame->addText->m3->SetValue("");
if(M4Name != 0) frame->addText->m4->SetValue("");
if(M5Name != 0) frame->addText->m5->SetValue("");
if(M6Name != 0) frame->addText->m6->SetValue("");
if(M7Name != 0) frame->addText->m7->SetValue("");
if(M8Name != 0) frame->addText->m8->SetValue("");
if(Comments != 0) frame->addText->cmt->SetValue("");
}
void Add(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Adding objects to database..." << "\n";
textWin << "\n";
if(KeyName == 0) { // Alert user that key name is not set
textWin << "Primary Key Name value is not set in db config file!"
<< "\n" << "Cannot add any objects." << "\n";
return;
}
APanelFrame->Show(TRUE); // Show the Add Panel Frame
}
void ChBtnProc(wxButton& but, wxCommandEvent& event)
{
UString sbuf, key_name; // Character input string buffers
long tag = (long)but.GetClientData() ;
int offset;
if(tag == CHANGE_BUTTON_SH) {
if(KeyName != 0) key_name = frame->changeText->key->GetValue();
// Remove any leading space from the key name entry
offset = key_name.Find(" ");
if(offset == 0) key_name.DeleteAt(offset, 1);
if(key_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
StrDB strdb(DB);
strdb.SetKM(key_name);
if(!(__LWORD__)strdb.FindObject()) {
sbuf = sbuf + "Could not find an entry for " + key_name;
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
cstrdb->Copy(strdb);
if(M2Name != 0)
if(cstrdb->GetM2())
frame->changeText->m2->SetValue(cstrdb->GetM2());
if(M3Name != 0)
if(cstrdb->GetM3())
frame->changeText->m3->SetValue(cstrdb->GetM3());
if(M4Name != 0)
if(cstrdb->GetM4())
frame->changeText->m4->SetValue(cstrdb->GetM4());
if(M5Name != 0)
if(cstrdb->GetM5())
frame->changeText->m5->SetValue(cstrdb->GetM5());
if(M6Name != 0)
if(cstrdb->GetM6())
frame->changeText->m6->SetValue(cstrdb->GetM6());
if(M7Name != 0)
if(cstrdb->GetM7())
frame->changeText->m7->SetValue(cstrdb->GetM7());
if(M8Name != 0)
if(cstrdb->GetM8())
frame->changeText->m8->SetValue(cstrdb->GetM8());
if(Comments != 0)
if(cstrdb->GetCM())
frame->changeText->cmt->SetValue(cstrdb->GetCM());
btn_ch_cm->Enable(1); // Enable the commit button
}
if(tag == CHANGE_BUTTON_CM) {
if(KeyName != 0) key_name = frame->changeText->key->GetValue();
// Remove any leading space from the key name entry
offset = key_name.Find(" ");
if(offset == 0) key_name.DeleteAt(offset, 1);
if(key_name == "") { // Check for a key name valid input
sbuf = sbuf + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
btn_ch_cm->Enable(0);
return;
}
StrDB changed(DB); // Buffer used to store changes
if(KeyName != 0) changed.SetKM(frame->changeText->key->GetValue());
if(M2Name != 0) changed.SetM2(frame->changeText->m2->GetValue());
if(M3Name != 0) changed.SetM3(frame->changeText->m3->GetValue());
if(M4Name != 0) changed.SetM4(frame->changeText->m4->GetValue());
if(M5Name != 0) changed.SetM5(frame->changeText->m5->GetValue());
if(M6Name != 0) changed.SetM6(frame->changeText->m6->GetValue());
if(M7Name != 0) changed.SetM7(frame->changeText->m7->GetValue());
if(M8Name != 0) changed.SetM8(frame->changeText->m8->GetValue());
if(Comments != 0) changed.SetCM(frame->changeText->cmt->GetValue());
// Disable the commit button after changing the object
btn_ch_cm->Enable(0);
if(changed.FullCompare(*cstrdb)) { // The object has not changed
sbuf = sbuf + "No changes to commit for " + cstrdb->GetKM();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
ClearChangePanel();
if(displaying_list) { //Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
UString key_name(changed.GetKM());
UString old_key_name(cstrdb->GetKM());
// If the key name is changed, ensure no duplicates are added
if(key_name != old_key_name) {
if((__LWORD__)changed.FindObject()) {
sbuf = sbuf + "An Entry for " + key_name + " already exists!";
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
Error->Message(sbuf.c_str());
if(displaying_list) { // Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
}
FAU oa = cstrdb->ObjectAddress(); // Record address before deleting
cstrdb->DeleteObject(); // Remove the object
changed.AddObject(0); // Add the changed object back to the database
sbuf = sbuf + "Commited changes for " + changed.GetKM();
frame->textWin->WriteText(sbuf.c_str());
frame->textWin->WriteText("\n");
ClearChangePanel();
// Update any list entries for display panel
if(displaying_list) { // Objects are being displayed
if(dllist->IsEmpty()) {
displaying_list = 0;
DPanelFrame->Show(FALSE);
return;
}
InMemCopy inmemcopy(cstrdb->GetKM(), oa, cstrdb->GetClassID());
DNode<InMemCopy> *prevptr = dllistptr;
dllistptr = (DNode<InMemCopy> *)dllist->Find(inmemcopy);
if(dllistptr) {
dllistptr->Data.key = changed.GetKM();
dllistptr->Data.object_address = changed.ObjectAddress();
dllistptr->Data.class_id = changed.GetClassID();
if(displaying_list) {
DPanelFrame->Show(TRUE);
DisplayObject(changed);
}
}
else {
dllistptr = prevptr;
dllistptr->Data.key = changed.GetKM();
dllistptr->Data.object_address = changed.ObjectAddress();
dllistptr->Data.class_id = changed.GetClassID();
if(displaying_list) {
DPanelFrame->Show(TRUE);
DisplayObject(changed);
}
}
}
}
if(tag == CHANGE_BUTTON_CANCEL) {
ClearChangePanel();
if(displaying_list) { // Objects are being displayed
if(!dllist->IsEmpty()) DPanelFrame->Show(TRUE);
}
btn_ch_cm->Enable(0);
return;
}
if(tag == CHANGE_BUTTON_CLOSE) {
ClearChangePanel();
CPanelFrame->Show(FALSE);
btn_ch_cm->Enable(0);
return;
}
if(tag == CHANGE_BUTTON_REVERT) {
if(KeyName != 0)
if(cstrdb->GetKM())
frame->changeText->key->SetValue(cstrdb->GetKM());
if(M2Name != 0)
if(cstrdb->GetM2())
frame->changeText->m2->SetValue(cstrdb->GetM2());
if(M3Name != 0)
if(cstrdb->GetM3())
frame->changeText->m3->SetValue(cstrdb->GetM3());
if(M4Name != 0)
if(cstrdb->GetM4())
frame->changeText->m4->SetValue(cstrdb->GetM4());
if(M5Name != 0)
if(cstrdb->GetM5())
frame->changeText->m5->SetValue(cstrdb->GetM5());
if(M6Name != 0)
if(cstrdb->GetM6())
frame->changeText->m6->SetValue(cstrdb->GetM6());
if(M7Name != 0)
if(cstrdb->GetM7())
frame->changeText->m7->SetValue(cstrdb->GetM7());
if(M8Name != 0)
if(cstrdb->GetM8())
frame->changeText->m8->SetValue(cstrdb->GetM8());
if(Comments != 0)
if(cstrdb->GetCM())
frame->changeText->cmt->SetValue(cstrdb->GetCM());
btn_ch_cm->Enable(0);
return;
}
}
void ClearChangePanel()
{
if(KeyName != 0) frame->changeText->key->SetValue("");
if(M2Name != 0) frame->changeText->m2->SetValue("");
if(M3Name != 0) frame->changeText->m3->SetValue("");
if(M4Name != 0) frame->changeText->m4->SetValue("");
if(M5Name != 0) frame->changeText->m5->SetValue("");
if(M6Name != 0) frame->changeText->m6->SetValue("");
if(M7Name != 0) frame->changeText->m7->SetValue("");
if(M8Name != 0) frame->changeText->m8->SetValue("");
if(Comments != 0) frame->changeText->cmt->SetValue("");
}
void Change(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Changing objects in database..." << "\n";
textWin << "\n";
if(KeyName == 0) { // Alert user that key name is not set
textWin << "Primary Key Name value is not set in db config file!"
<< "\n" << "Cannot change any objects." << "\n";
return;
}
CPanelFrame->Show(TRUE); // Show the Add Panel Frame
}
void Remove(MyTextWindow &textWin, char *keyNM)
{
if(KeyName == 0) return;
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
textWin.Clear();
textWin << "Removing object from database..." << "\n";
UString key_name;
UString comp;
char *buf;
if(!keyNM) {
comp = comp + "Enter " + KeyName + " to Remove:";
buf = wxGetTextFromUser(comp.c_str(), "String Input");
if(!buf) {
textWin << "Canceled." << "\n";
return;
}
key_name = buf;
// Remove any leading space from the key name entry
int offset = key_name.Find(" ");
if(offset == 0) key_name.DeleteAt(offset, 1);
if(key_name == "") { // Check for a key name valid input
comp.DeleteAt(0, comp.length());
comp = comp + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(comp.c_str());
frame->textWin->WriteText("\n");
Error->Message(comp.c_str());
return;
}
}
else
key_name = keyNM; // Key name memeber
StrDB strdb(DB);
strdb.SetKM(key_name);
FAU addr = strdb.FindObject();
if(!addr) {
comp.DeleteAt(0, comp.length());
comp = comp + "Could not find an entry for: " + key_name.c_str();
Error->Message(comp.c_str());
textWin << comp.c_str() << "\n";
return;
}
int yn = wxMessageBox("Are you sure you want to remove",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxNO) return;
InMemCopy listdata(strdb.GetKM(), strdb.ObjectAddress(),
strdb.GetClassID());
strdb.DeleteObject();
textWin << "Removed entry for: " << key_name.c_str() << "\n";
// Update display object panel list
if(displaying_list) {
if(dllist->IsEmpty()) {
displaying_list = 0;
DPanelFrame->Show(TRUE);
return;
}
DNode<InMemCopy> *dllptr = 0;
dllptr = (DNode<InMemCopy> *)dllist->Find(listdata);
if(dllptr) {
dllist->Delete(dllptr);
wxCommandEvent wxevent1(wxEVENT_TYPE_BUTTON_COMMAND);
DsBtnProc(*btn_ds_nx, wxevent1); // Simulate pushing the Next Button
}
}
}
void DsBtnProc(wxButton& but, wxCommandEvent& event)
{
char *sbuf = 0; // Character string buffer
long tag = (long)but.GetClientData() ;
StrDB strdb(DB);
if(tag == DISPLAY_BUTTON_NX) {
if(!dllistptr) return;
if(!dllist) return;
if(dllist->IsEmpty()) {
ClearDisplayPanel();
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
dllistptr = dllistptr->GetNext();
if(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
else {
wxMessageBox("Reached the end of the list\n",
"Program Message", wxOK|wxCENTRE);
dllistptr = dllist->GetFront();
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
}
if(tag == DISPLAY_BUTTON_PREV) {
if(!dllistptr) return;
if(!dllist) return;
if(dllist->IsEmpty()) {
ClearDisplayPanel();
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
dllistptr = dllistptr->GetPrior();
if(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
else {
wxMessageBox("Reached the beginning of the list\n",
"Program Message", wxOK|wxCENTRE);
dllistptr = dllist->GetBack();
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
}
if(tag == DISPLAY_BUTTON_CHANGE) {
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(dllist->IsEmpty()) {
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(!dllist->IsEmpty()) {
strdb.ReadObject(dllistptr->Data.object_address);
cstrdb->Copy(strdb);
}
else
cstrdb->Copy(*dstrdb);
frame->changeText->key->SetValue(cstrdb->GetKM());
wxCommandEvent wxevent(wxEVENT_TYPE_BUTTON_COMMAND);
ChBtnProc(*btn_ch_sh, wxevent); // Simulate pushing the Search Button
CPanelFrame->Show(TRUE); // Show the Change Panel Frame
}
if(tag == DISPLAY_BUTTON_CLOSE) {
ClearDisplayPanel();
displaying_list = 0;
DPanelFrame->Show(FALSE);
CPanelFrame->Show(FALSE);
dllist->Clear();
return;
}
if(tag == DISPLAY_BUTTON_REMOVE) {
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
if(dllist->IsEmpty()) {
wxMessageBox("The display list is empty\n",
"Program Message", wxOK|wxCENTRE);
return;
}
else
Remove(*frame->textWin, dstrdb->GetKM());
}
}
void ClearDisplayPanel()
{
if(KeyName != 0) frame->displayText->key->SetValue("");
if(M2Name != 0) frame->displayText->m2->SetValue("");
if(M3Name != 0) frame->displayText->m3->SetValue("");
if(M4Name != 0) frame->displayText->m4->SetValue("");
if(M5Name != 0) frame->displayText->m5->SetValue("");
if(M6Name != 0) frame->displayText->m6->SetValue("");
if(M7Name != 0) frame->displayText->m7->SetValue("");
if(M8Name != 0) frame->displayText->m8->SetValue("");
if(Comments != 0) frame->displayText->cmt->SetValue("");
}
void DisplayObject(StrDB &strdb)
{
dstrdb->Copy(strdb); // Initialize global display object
if(KeyName != 0)
if(strdb.GetKM())
frame->displayText->key->SetValue(strdb.GetKM());
if(M2Name != 0)
if(strdb.GetM2())
frame->displayText->m2->SetValue(strdb.GetM2());
if(M3Name != 0)
if(strdb.GetM3())
frame->displayText->m3->SetValue(strdb.GetM3());
if(M4Name != 0)
if(strdb.GetM4())
frame->displayText->m4->SetValue(strdb.GetM4());
if(M5Name != 0)
if(strdb.GetM5())
frame->displayText->m5->SetValue(strdb.GetM5());
if(M6Name != 0)
if(strdb.GetM6())
frame->displayText->m6->SetValue(strdb.GetM6());
if(M7Name != 0)
if(strdb.GetM7())
frame->displayText->m7->SetValue(strdb.GetM7());
if(M8Name != 0)
if(strdb.GetM8())
frame->displayText->m8->SetValue(strdb.GetM8());
if(Comments != 0)
if(strdb.GetCM())
frame->displayText->cmt->SetValue(strdb.GetCM());
displaying_list = 1;
DPanelFrame->Show(TRUE);
}
int LoadIndexKeys()
{
// Clear the doubly linked list
dllist->Clear();
BtreeWalker btw(DB->Index());
unsigned num_objects = btw.Sort(LoadKeys);
if(num_objects > 0) print_list = 1;
return num_objects;
}
void DisplayDB(MyTextWindow &textWin)
{
if(KeyName == 0) return;
textWin.Clear();
textWin << "Displaying the database objects." << "\n";
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
num_objects = LoadIndexKeys();
if(num_objects == 0) {
textWin << "The database is empty." << "\n";
dllist->Clear();
return;
}
else
textWin << "Displaying " << num_objects << " objects..." << "\n";
// Initialize the doubly list node pointer
dllistptr = dllist->GetFront();
// Display the first object
StrDB strdb(DB);
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
void FindBy(MyTextWindow &textWin, const char *MemberName, StrDBItem item)
{
if(MemberName == 0) return;
textWin.Clear();
textWin << "Searching for object by " << (char *)MemberName << "\n";
UString comp;
comp = comp + "Enter complete string or use " + WildCard + \
" for a wild card:";
char *buf = wxGetTextFromUser(comp.c_str(), (char *)MemberName);
if(!buf) {
textWin << "Canceled." << "\n";
return;
}
UString name(buf);
// Remove any leading space from the key name entry
unsigned offset = name.Find(" ");
if(offset == 0) name.DeleteAt(offset, 1);
if(name == "") { // Check for a key name valid input
comp.DeleteAt(0, comp.length());
comp = comp + "Invalid " + MemberName + " input!";
frame->textWin->WriteText(comp.c_str());
frame->textWin->WriteText("\n");
Error->Message(comp.c_str());
return;
}
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
StrDB strdb(DB);
offset = name.Find(WildCard); // Look for wild card character
if(offset == UString::NoMatch) { // No wild cards found
strdb.SetKM(buf);
StrDBSearch(strdb, item, name, textWin);
return;
}
else
StrDBSearch(strdb, item, name, textWin, WildCard);
}
void StrDBSearch(StrDB &strdb, StrDBItem item, UString &str,
MyTextWindow &textWin, const char *wildcard)
{
textWin << "Searching for " << str.c_str() << "\n";
int offset;
offset = ObjectsFound = 0;
if(wildcard != 0) {
while(1) { // Remove the wild card characters from the string
offset = str.Find(wildcard, offset);
if (offset == UString::NoMatch) break;
str.DeleteAt(offset, strlen(wildcard));
offset++;
}
}
// Ensure that the memory buffers and the file data
// stay in sync during multiple file access.
DB->Index()->TestTree();
dllist->Clear();
if(wildcard != 0)
BtreeSearch(DB->Index(), item, strdb, str, 1);
else
BtreeSearch(DB->Index(), item, strdb, str);
if(ObjectsFound == 0) {
textWin << "No matches found." << "\n";
return;
}
else
num_objects = ObjectsFound;
dllistptr = dllist->GetFront();
UString comp;
int yn;
if(ObjectsFound > 1) { // Found multiple matches
textWin << "Found " << ObjectsFound << " matching." << "\n";
char intbuf[100];
sprintf(intbuf, "%d", ObjectsFound);
comp = comp + "Found " + intbuf + " matching.\nDisplay the objects?";
yn = wxMessageBox(comp.c_str(), "Program Message", wxYES_NO|wxCENTRE);
}
else {
textWin << "Found matching entry for: " << str.c_str() << "\n";
comp = comp + "Found matching entry for: " + str + \
"\nDisplay the object?";
yn = wxMessageBox(comp.c_str(), "Program Message", wxYES_NO|wxCENTRE);
}
if(yn == wxNO) {
dllist->Clear();
num_objects = 0;
return;
}
// Display the first object
strdb.ReadObject(dllistptr->Data.object_address);
DisplayObject(strdb);
}
void ExportToASCII(MyTextWindow &textWin)
{
const char dchar = '\t'; // Text delimiter
const char filter = '\t'; // Filter out tabs
const char *Fill = "None"; // Fill character string
int yn, exports = 0;
textWin.Clear();
textWin << "Exporting database to ASCII file delimited by tabs..." << "\n";
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
if(displaying_list) {
yn = wxMessageBox("Export display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else {
yn = wxNO;
}
if(yn == wxNO) LoadIndexKeys();
if(dllist->IsEmpty()) LoadIndexKeys();
char *FileName = wxFileSelector("Export to file:", NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Export canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Export canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Exporting database to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
StrDB strdb(DB);
// Write the item bar to the file first
if(KeyName != 0) {
ASPrint(KeyName, stream, strlen(KeyName));
stream << dchar;
}
if(M2Name != 0) {
ASPrint(M2Name, stream, strlen(M2Name));
stream << dchar;
}
if(M3Name != 0) {
ASPrint(M3Name, stream, strlen(M3Name));
stream << dchar;
}
if(M4Name != 0) {
ASPrint(M4Name, stream, strlen(M4Name));
stream << dchar;
}
if(M5Name != 0) {
ASPrint(M5Name, stream, strlen(M5Name));
stream << dchar;
}
if(M6Name != 0) {
ASPrint(M6Name, stream, strlen(M6Name));
stream << dchar;
}
if(M7Name != 0) {
ASPrint(M7Name, stream, strlen(M7Name));
stream << dchar;
}
if(M8Name != 0) {
ASPrint(M8Name, stream, strlen(M8Name));
stream << dchar;
}
if(Comments != 0) {
ASPrint(Comments, stream, strlen(Comments));
}
stream << asLineFeed;
dllistptr = dllist->GetFront();
while(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
if(KeyName != 0) {
ASPrint(strdb.GetKM(), filter, stream, strlen(strdb.GetKM()));
stream << dchar;
}
if(M2Name != 0) {
if(!*strdb.GetM2()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM2(), filter, stream, strlen(strdb.GetM2()));
stream << dchar;
}
if(M3Name != 0) {
if(!*strdb.GetM3()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM3(), filter, stream, strlen(strdb.GetM3()));
stream << dchar;
}
if(M4Name != 0) {
if(!*strdb.GetM4()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM4(), filter, stream, strlen(strdb.GetM4()));
stream << dchar;
}
if(M5Name != 0) {
if(!*strdb.GetM5()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM5(), filter, stream, strlen(strdb.GetM5()));
stream << dchar;
}
if(M6Name != 0) {
if(!*strdb.GetM6()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM6(), filter, stream, strlen(strdb.GetM6()));
stream << dchar;
}
if(M7Name != 0) {
if(!*strdb.GetM7()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM7(), filter, stream, strlen(strdb.GetM7()));
stream << dchar;
}
if(M8Name != 0) {
if(!*strdb.GetM8()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetM8(), filter, stream, strlen(strdb.GetM8()));
stream << dchar;
}
if(Comments != 0) {
if(!*strdb.GetCM()) ASPrint(Fill, stream, strlen(Fill));
else ASPrint(strdb.GetCM(), filter, stream, strlen(strdb.GetCM()));
}
stream << asLineFeed;
exports++;
dllistptr = dllistptr->GetNext();
}
textWin << "Exported " << exports << " objects." << "\n";
stream.close();
}
void ImportFromASCII(MyTextWindow &textWin)
{
if(KeyName == 0) return;
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
char words[MAXWORDS][MAXWORDLENGTH];
int num;
const int MaxLine = 512;
char LineBuffer[MaxLine];
UString sbuf;
const char dchar = '\t'; // Text delimiter
// wxWindows single choice index box setup
int ch = -1;
const int CHArray = 4;
char *ch_array[CHArray] = {
"Update this entry",
"Skip this entry",
"Update all entries without prompting",
"Quit this import"
};
enum ICHOICES {
UPDATE_ENTRY,
UPDATE_SKIP,
UPDATE_ALL,
QUIT_THIS
};
textWin.Clear();
textWin << "Importing database from ASCII file delimited by tabs..." << "\n";
char *FileName = wxFileSelector("Import from file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Import canceled." << "\n";
return; // No vaild file name
}
ifstream stream(FileName, ios::in|ios::nocreate);
textWin << "Importing database from: " << FileName << "\n";
if(!stream) { // Could not open the stream
textWin << "Could not open file: " << FileName << "\n";
return;
}
textWin << "Importing..." << "\n";
SNode<UString> *sllistptr; // Linked list node pointer
SLList<UString> sllist; // Linked list
while(!stream.eof())
{
// Read in file line by line
stream.getline(LineBuffer, MaxLine);
// Copy contents of the array to temporary holding buffer
sbuf = LineBuffer;
// Load file data into singly-linked list
sllistptr = sllist.StoreNode(sbuf);
// Clear the string buffer
sbuf.DeleteAt(0, sbuf.length());
if(!sllistptr) { // Out of memory
stream.close();
sllist.Clear();
return;
}
}
stream.close();
StrDB strdb(DB);
StrDB strdba(DB);
StrDB ob(DB);
int linecount = 0;
int imports = 0;
int updates = 0;
int updateall = 0;
int ObjectItems = 1; // Number of class data members
// Calculate the number of objects
if(M2Name != 0) ObjectItems++;
if(M3Name != 0) ObjectItems++;
if(M4Name != 0) ObjectItems++;
if(M5Name != 0) ObjectItems++;
if(M6Name != 0) ObjectItems++;
if(M7Name != 0) ObjectItems++;
if(M8Name != 0) ObjectItems++;
if(Comments != 0) ObjectItems++;
sllistptr = sllist.GetFront();
while(!sllist.IsHeader(sllistptr)) {
if(parse(sllistptr->Data.c_str(), words, &num, dchar) == 1) {
textWin << "Parse error!" << "\n";
break;
}
linecount++;
if(num != ObjectItems && (num != 0 && num != 1)) {
textWin << "Error in " << FileName << " import file!" << "\n";
if(num > ObjectItems)
textWin << "To many items on line: ";
if(num < ObjectItems)
textWin << "Not enough items on line: ";
textWin << linecount << "\n";
int yn = wxMessageBox("Error in import file! Continue?",
"Program Message", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
sllist.Clear();
return;
}
}
if(num == ObjectItems && *words[0] != 0) {
strdb.SetKM(words[0]);
if(M2Name != 0) strdb.SetM2(words[1]);
if(M3Name != 0) strdb.SetM3(words[2]);
if(M4Name != 0) strdb.SetM4(words[3]);
if(M5Name != 0) strdb.SetM5(words[4]);
if(M6Name != 0) strdb.SetM6(words[5]);
if(M7Name != 0) strdb.SetM7(words[6]);
if(M8Name != 0) strdb.SetM8(words[7]);
if(Comments != 0) strdb.SetCM(words[8]);
strdba.SetKM(strdb.GetKM());
FAU addr = strdba.FindObject();
if(addr) {
if(updateall == 0) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + strdb.GetKM() + " entry already exists.\n" + \
"Select your choice and click on OK";
ch = wxGetSingleChoiceIndex(sbuf.c_str(), "Importing Objects",
CHArray, ch_array, frame);
}
if(updateall == 1) ch = UPDATE_ALL;
switch(ch) {
case UPDATE_ALL:
updateall = 1;
updates++;
ob.Copy(strdba);
if(strdb.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
strdb.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case UPDATE_SKIP:
break;
case UPDATE_ENTRY:
updates++;
ob.Copy(strdba);
if(strdb.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
strdb.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case QUIT_THIS:
textWin << "Import cancled." << "\n";
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
sllist.Clear();
return;
default:
break;
}
if(updateall == 1) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
}
else {
// Nothing to do
}
}
else {
// Ensure that the template does not get added to the file
if(CaseICmp(KeyName, words[0]) != 0) {
FAU addr = strdb.AddObject(0); // Write the object to the file
imports++;
if(!addr) {
textWin << "Could not add:" << strdb.GetKM()
<< " to database" << "\n";
imports--;
}
}
}
}
sllistptr = sllistptr->GetNext();
}
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
sllist.Clear();
}
void BackUp(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Backing up the database to another file..." << "\n";
char *FileName = wxFileSelector("Backup to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Backup canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Export canceled." << "\n";
return;
}
if(!wxRemoveFile(FileName)) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
}
POD newdb(FileName, FileName);
int items = 0;
StrDB strdb(&newdb);
StrDB strdb_old(DB);
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
CachePointer nxt(*DB->Index()->GetCache());
BtreeWalkerb tw(DB->Index(), btINORDER);
nxt = DB->Index()->GetRoot();
while((__LWORD__)nxt != 0) {
nxt = tw.Next();
if((__LWORD__)nxt) {
for(int i = 0; i < nxt->cnt; i++) {
strdb_old.ReadObject(nxt->entry[i].object_address);
strdb.Copy(strdb_old);
strdb.AddObject(0);
items++;
}
}
}
textWin << "Backed up " << items << " objects to " << FileName << "\n";
}
void Merge(MyTextWindow &textWin)
{
if(!AdminRights) {
wxMessageBox("You do not have Admin User Privileges\n",
"Program Message", wxOK|wxCENTRE);
return;
}
// wxWindows single choice index box setup
int ch = -1;
const int CHArray = 4;
char *ch_array[CHArray] = {
"Update this entry",
"Skip this entry",
"Update all entries without prompting",
"Quit this merge"
};
enum ICHOICES {
UPDATE_ENTRY,
UPDATE_SKIP,
UPDATE_ALL,
QUIT_THIS
};
textWin.Clear();
textWin << "Merging the contents of another database..." << "\n";
char *FileName = wxFileSelector("Merge from file:", NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Merge canceled." << "\n";
return; // No vaild file name
}
POD newdb(FileName, FileName);
StrDB strdb(&newdb);
StrDB strdba(DB);
StrDB ob(DB);
FAU existing;
FAU addr;
UString sbuf;
int imports = 0;
int updates = 0;
int updateall = 0;
FAU oa; // Object Address
VBlockHeader vb; // Variable Block Header
ObjectHeader oh; // Object Header
FAU vbdfileEOF = newdb.OpenDatabase()->GetEOF();
addr = 0;
addr = newdb.OpenDatabase()->FindFirstVB(addr); // Search the entire file
if(addr == 0) {
textWin << "No variable blocks found in file: " << FileName << "\n";
return;
}
textWin << "Merging..." << "\n";
while(1) {
if(addr >= vbdfileEOF) break;
newdb.OpenDatabase()->Read(&vb, sizeof(VBlockHeader), addr);
if(vb.CkWord == CheckWord) {
if((__SBYTE__)vb.VBStatus == NormalVB) {
oa = addr + sizeof(VBlockHeader);
newdb.OpenDatabase()->Read(&oh, sizeof(ObjectHeader), oa);
if(oh.ClassID == strdb.GetClassID()) {
strdb.ReadObject(oa);
strdba.SetKM(strdb.GetKM());
existing = strdba.FindObject();
if(existing) {
if(updateall == 0) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + strdba.GetKM() + " entry already exists.\n" + \
"Select your choice and click on OK";
ch = wxGetSingleChoiceIndex(sbuf.c_str(), "Importing Objects",
CHArray, ch_array, frame);
}
if(updateall == 1) ch = UPDATE_ALL;
switch(ch) {
case UPDATE_ALL:
updateall = 1;
updates++;
ob.Copy(strdb);
if(strdb.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
ob.Copy(strdb);
ob.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case UPDATE_SKIP:
break;
case UPDATE_ENTRY:
updates++;
ob.Copy(strdb);
if(strdb.FullCompare(ob)) break; // The object has not changed
ob.DeleteObject();
ob.Copy(strdb);
ob.AddObject(0);
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
break;
case QUIT_THIS:
textWin << "Merge cancled." << "\n";
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
return;
default:
break;
}
if(updateall == 1) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Updating entry for: " + strdb.GetKM();
textWin << sbuf.c_str() << "\n";
frame->SetStatusText(sbuf.c_str());
}
else {
// Nothing to do
}
}
else {
strdba.Copy(strdb);
FAU rvaddr = strdba.AddObject(0); // Write the object to the file
imports++;
if(!rvaddr) {
textWin << "Could not add:" << strdb.GetKM()
<< " to database" << "\n";
imports--;
}
}
}
}
addr = addr + vb.Length; // Goto the next variable block
}
else {
addr = newdb.OpenDatabase()->VBSearch(addr);
if(!addr) break;
}
}
textWin << "Imported " << imports << " objects." << "\n";
if(updates) {
textWin << "Updated " << updates << " objects." << "\n";
}
}
void CreateTemplate(MyTextWindow &textWin)
{
const char dchar = '\t'; // Text delimiter
textWin.Clear();
textWin << "Creating template file delimited by tabs..." << "\n";
char *FileName = wxFileSelector("Template file to create:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Creating template canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Creating template canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Creating template file: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
if(KeyName != 0) {
ASPrint(KeyName, stream, strlen(KeyName));
stream << dchar;
}
if(M2Name != 0) {
ASPrint(M2Name, stream, strlen(M2Name));
stream << dchar;
}
if(M3Name != 0) {
ASPrint(M3Name, stream, strlen(M3Name));
stream << dchar;
}
if(M4Name != 0) {
ASPrint(M4Name, stream, strlen(M4Name));
stream << dchar;
}
if(M5Name != 0) {
ASPrint(M5Name, stream, strlen(M5Name));
stream << dchar;
}
if(M6Name != 0) {
ASPrint(M6Name, stream, strlen(M6Name));
stream << dchar;
}
if(M7Name != 0) {
ASPrint(M7Name, stream, strlen(M7Name));
stream << dchar;
}
if(M8Name != 0) {
ASPrint(M8Name, stream, strlen(M8Name));
stream << dchar;
}
if(Comments != 0) {
ASPrint(Comments, stream, strlen(Comments));
}
stream << asLineFeed;
textWin << "Finished." << "\n";
stream.close();
}
void ASCIIPrintAll(MyTextWindow &textWin)
{
ASCIIPrint(PORTRAIT, textWin);
}
void ASCIIPrintAllLong(MyTextWindow &textWin)
{
ASCIIPrint(LANDSCAPE, textWin);
}
int ASCIIPrint(PrintMode mode, MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Printing database to ASCII file..." << "\n";
int yn = 0;
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return 0;
}
if(displaying_list) {
yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else {
yn = wxNO;
}
if(yn == wxNO) LoadIndexKeys();
if(dllist->IsEmpty()) LoadIndexKeys();
char *FileName = wxFileSelector("Print database to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "ASCII print canceled." << "\n";
return 0; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "ASCII print canceled." << "\n";
return 0;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return 0;
}
StrDB strdb(DB);
unsigned count = 0;
if(mode == LANDSCAPE)
PrintItemBar(stream, 0);
else
PrintItemBar(stream);
dllistptr = dllist->GetFront();
textWin << "Printing..." << "\n";
while(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
switch(mode) {
case PORTRAIT:
PrintLineByLine(strdb, stream);
break;
case LANDSCAPE:
PrintLineByLine(strdb, stream, 0);
break;
default:
return 0;
}
count++;
dllistptr = dllistptr->GetNext();
}
textWin << "Finished." << "\n";
stream.close();
return count;
}
void PrintItemBar(ofstream &stream, int abv)
{
int i = 0;
if(KeyName != 0) ASPrint(KeyName, stream, StringOffset+1);
if(M2Name != 0) ASPrint(M2Name, stream, StringOffset+1);
if(M3Name != 0) ASPrint(M3Name, stream, StringOffset+1);
if(M4Name != 0) ASPrint(M4Name, stream, StringOffset+1);
if(abv) { // Print abbreviated list for portrait print outs
if(M5Name != 0) ASPrint(M5Name, stream, StringOffset);
stream << asLineFeed;
i = 0;
while (i++ < asPrintCols-1) stream << '=';
stream << asLineFeed;
return;
}
else { // Print full listing for landscape print outs
if(M5Name != 0) ASPrint(M5Name, stream, StringOffset+1);
if(M6Name != 0) ASPrint(M6Name, stream, StringOffset+1);
if(M7Name != 0) ASPrint(M7Name, stream, StringOffset+1);
if(M8Name != 0) ASPrint(M8Name, stream, StringOffset);
stream << asLineFeed;
i = 0;
while (i++ < asPrintColsLong-1) stream << '=';
stream << asLineFeed;
}
}
void PrintLineByLine(StrDB &strdb, ofstream &stream, int abv)
{
int i = 0;
if(KeyName != 0) ASPrint(strdb.GetKM(), stream, StringOffset+1);
if(M2Name != 0) ASPrint(strdb.GetM2(), stream, StringOffset+1);
if(M3Name != 0) ASPrint(strdb.GetM3(), stream, StringOffset+1);
if(M4Name != 0) ASPrint(strdb.GetM4(), stream, StringOffset+1);
if(abv) { // Print abbreviated list for portrait print outs
if(M5Name != 0) ASPrint(strdb.GetM5(), stream, StringOffset);
stream << asLineFeed;
i = 0;
while (i++ < asPrintCols-1) stream << '-';
stream << asLineFeed;
return;
}
else { // Print full listing for landscape print outs
if(M5Name != 0) ASPrint(strdb.GetM5(), stream, StringOffset+1);
if(M6Name != 0) ASPrint(strdb.GetM6(), stream, StringOffset+1);
if(M7Name != 0) ASPrint(strdb.GetM7(), stream, StringOffset+1);
if(M8Name != 0) ASPrint(strdb.GetM8(), stream, StringOffset);
stream << asLineFeed;
i = 0;
while (i++ < asPrintColsLong-1) stream << '-';
stream << asLineFeed;
}
}
void ASCIIPrintObject(MyTextWindow &textWin, char *keyNM)
{
if(KeyName == 0) return;
textWin.Clear();
textWin << "Printing object to ASCII file..." << "\n";
UString key_name;
UString comp;
char *buf;
if(!keyNM) {
comp = comp + "Enter " + KeyName + " to print:";
buf = wxGetTextFromUser(comp.c_str(), "String Input");
if(!buf) {
textWin << "Canceled." << "\n";
return;
}
key_name = buf;
// Remove any leading space from the key name entry
int offset = key_name.Find(" ");
if(offset == 0) key_name.DeleteAt(offset, 1);
if(key_name == "") { // Check for a key name valid input
comp.DeleteAt(0, comp.length());
comp = comp + "Invalid " + KeyName + " input!";
frame->textWin->WriteText(comp.c_str());
frame->textWin->WriteText("\n");
Error->Message(comp.c_str());
return;
}
}
else
key_name = keyNM; // Key name memeber
StrDB strdb(DB);
strdb.SetKM(key_name);
FAU addr = strdb.FindObject();
if(!addr) {
comp.DeleteAt(0, comp.length());
comp = comp + "Could not find an entry for: " + key_name.c_str();
Error->Message(comp.c_str());
textWin << comp.c_str() << "\n";
return;
}
PrintObject(strdb, textWin);
}
void PrintObject(StrDB &strdb, MyTextWindow &textWin)
{
const char *separator = " = ";
const char *cseparator = ": ";
char *FileName = wxFileSelector("Printing object to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "ASCII print canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "ASCII print canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
if(KeyName != 0) {
ASPrint(KeyName, stream, strlen(KeyName));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetKM(), stream, strlen(strdb.GetKM()));
stream << asLineFeed;
}
if(M2Name != 0) {
ASPrint(M2Name, stream, strlen(M2Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM2(), stream, strlen(strdb.GetM2()));
stream << asLineFeed;
}
if(M3Name != 0) {
ASPrint(M3Name, stream, strlen(M3Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM3(), stream, strlen(strdb.GetM3()));
stream << asLineFeed;
}
if(M4Name != 0) {
ASPrint(M4Name, stream, strlen(M4Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM4(), stream, strlen(strdb.GetM4()));
stream << asLineFeed;
}
if(M5Name != 0) {
ASPrint(M5Name, stream, strlen(M5Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM5(), stream, strlen(strdb.GetM5()));
stream << asLineFeed;
}
if(M6Name != 0) {
ASPrint(M6Name, stream, strlen(M6Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM6(), stream, strlen(strdb.GetM6()));
stream << asLineFeed;
}
if(M7Name != 0) {
ASPrint(M7Name, stream, strlen(M7Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM7(), stream, strlen(strdb.GetM7()));
stream << asLineFeed;
}
if(M8Name != 0) {
ASPrint(M8Name, stream, strlen(M8Name));
ASPrint(separator, stream, strlen(separator));
ASPrint(strdb.GetM8(), stream, strlen(strdb.GetM8()));
stream << asLineFeed;
}
if(Comments != 0) {
ASPrint(Comments, stream, strlen(Comments));
ASPrint(cseparator, stream, strlen(cseparator));
ASPrint(strdb.GetCM(), stream, strlen(strdb.GetCM()));
stream << asLineFeed;
}
textWin << "Finished." << "\n";
stream.close();
}
void CompareIndexFile(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Comparing the index file to the data file..." << "\n";
StrDB strdb(DB);
int rv = strdb.CompareIndex();
if(!rv) {
textWin << "The index file does not match the data file!" << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
textWin << "The index file checks good." << "\n";
}
void RebuildIndexFile(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Rebuilding the index file..." << "\n";
UString sbuf;
char *FileName = wxFileSelector("Enter name for new index file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "Rebuild canceled." << "\n";
return; // No vaild file name
}
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
int yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "Rebuild canceled." << "\n";
return;
}
if(!wxRemoveFile(FileName)) {
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
}
StrDB strdb(DB);
int rv = strdb.RebuildIndexFile(FileName);
if(!rv) {
textWin << "The index file was not rebuilt!" << "\n";
return;
}
textWin << "The index file was rebuilt." << "\n";
textWin << "A new index file named:\n"
<< FileName << " was created." << "\n";
}
int PrintPSItemBar(ofstream &stream, PostScriptDrv &psdrv,
int x_offset, int char_offset, int cell_len)
{
if(KeyName != 0) {
psdrv.PrintLine((char *)KeyName, cell_len, stream);
x_offset += char_offset;
}
if(M2Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M2Name, cell_len, stream);
x_offset += char_offset;
}
if(M3Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M3Name, cell_len, stream);
x_offset += char_offset;
}
if(M4Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M4Name, cell_len, stream);
x_offset += char_offset;
}
if(M5Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M5Name, cell_len, stream);
x_offset += char_offset;
}
if(M6Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M6Name, cell_len, stream);
x_offset += char_offset;
}
if(M7Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M7Name, cell_len, stream);
x_offset += char_offset;
}
if(M8Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)M8Name, cell_len, stream);
x_offset += char_offset;
}
if(Comments != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine((char *)Comments, cell_len, stream);
x_offset += char_offset;
}
return x_offset;
}
void PostScriptPrint(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Printing database to PostScript file..." << "\n";
int yn, i;
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
// Setup the default values for user configurable PostScript parameters
int cell_len = 19;
double font_size = 7;
int orientation = 1;
const int DocNameLen = 255;
char psDocName[DocNameLen];
for(i = 0; i < DocNameLen; i++) psDocName[i] = 0;
strcpy(psDocName, ProgramName);
PostScriptDrv::PSPaperSizes paper_code = PostScriptDrv::LETTER_SIZE;
PostScriptDrv::PSFonts item_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
PostScriptDrv::PSFonts cell_font = PostScriptDrv::COURIER;
// Load the PostScript configuration from the config file
char *CurrentCfgFile;
char *CfgFile;
Config *CfgData = new Config;
// Look for CfgFile name in environment
if((CurrentCfgFile = getenv(EnvSetting)) == 0)
CfgFile = (char *)DefaultCfgFile;
else
CfgFile = CurrentCfgFile;
int FileStatus = CfgData->Load((char *)CfgFile);
if(FileStatus) { // Found a valid config file
// *********************************************************** //
// Add all PostScript config file entries here
// *********************************************************** //
int int_val = 0;
double dfp_val = 0;
char *str_val = 0;
int_val = CfgData->GetIntValue("CellLength");
if(int_val > 0) cell_len = int_val;
dfp_val = CfgData->GetDFPValue("FontSize");
if(dfp_val > 0) font_size = dfp_val;
str_val = CfgData->GetStrValue("Orientation");
if(str_val != 0) {
if(strcmp(str_val, "PORTRAIT") == 0) orientation = 0;
str_val = 0;
}
str_val = CfgData->GetStrValue("PaperSize");
if(str_val != 0) {
if(strcmp(str_val, "LETTER") == 0)
paper_code = PostScriptDrv::LETTER_SIZE;
if(strcmp(str_val, "LEGAL") == 0)
paper_code = PostScriptDrv::LEGAL_SIZE;
if(strcmp(str_val, "TABLOID") == 0)
paper_code = PostScriptDrv::TABLOID_SIZE;
if(strcmp(str_val, "A3") == 0) paper_code = PostScriptDrv::A3_SIZE;
if(strcmp(str_val, "A4") == 0) paper_code = PostScriptDrv::A4_SIZE;
str_val = 0;
}
str_val = CfgData->GetStrValue("ItemBarFont");
if(str_val != 0) {
if(strcmp(str_val, "COURIER") == 0)
item_font = PostScriptDrv::COURIER;
if(strcmp(str_val, "COURIER_BOLD") == 0)
item_font = PostScriptDrv::COURIER_BOLD;
if(strcmp(str_val, "COURIER_OBLIQUE") == 0)
item_font = PostScriptDrv::COURIER_OBLIQUE;
if(strcmp(str_val, "COURIER_BOLD_OBLIQUE") == 0)
item_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
str_val = 0;
}
str_val = CfgData->GetStrValue("CellFont");
if(str_val != 0) {
if(strcmp(str_val, "COURIER") == 0)
cell_font = PostScriptDrv::COURIER;
if(strcmp(str_val, "COURIER_BOLD") == 0)
cell_font = PostScriptDrv::COURIER_BOLD;
if(strcmp(str_val, "COURIER_OBLIQUE") == 0)
cell_font = PostScriptDrv::COURIER_OBLIQUE;
if(strcmp(str_val, "COURIER_BOLD_OBLIQUE") == 0)
cell_font = PostScriptDrv::COURIER_BOLD_OBLIQUE;
}
str_val = CfgData->GetStrValue("psDocumentName");
if(str_val != 0) {
for(i = 0; i < DocNameLen; i++) psDocName[i] = 0;
strcpy(psDocName, str_val);
}
// *********************************************************** //
}
CfgData->UnLoad(); // Unload the Config file from memory
if(displaying_list) {
yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else {
yn = wxNO;
}
if(yn == wxNO) LoadIndexKeys();
if(dllist->IsEmpty()) LoadIndexKeys();
char *FileName = wxFileSelector("Print database to PostScript file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "PostScript print canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "PostScript print canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
PostScriptDrv psdrv;
psdrv.Copies(1);
// Setup the PostScript driver
psdrv.SetPaperSize(paper_code);
psdrv.SetFont(cell_font, font_size);
psdrv.UseHeader();
if(orientation == 1) psdrv.LandScapeMode();
psdrv.SetDocumentName(psDocName);
char time_buf[255]; // Buffer used to hold time/date string
GetSystemTime(time_buf);
psdrv.SetDateString(time_buf);
psdrv.DocumentSetup();
psdrv.Prologue(stream);
psdrv.MediaSetup(stream);
StrDB strdb(DB);
int char_offset = int((cell_len + 1) * psdrv.CharWidth());
int x_offset;
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
int lines = 4;
psdrv.StartPage(psdrv.page_count + 1, stream);
psdrv.row = psdrv.StartY();
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.ChangeFont(stream, item_font, font_size);
x_offset = PrintPSItemBar(stream, psdrv, x_offset, char_offset, cell_len);
psdrv.ChangeFont(stream, cell_font, font_size);
int line_points;
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.row -= (int)psdrv.FontSize();
lines++;
psdrv.drawThickLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= THICK_LINE_WIDTH + psdrv.FontSize();
lines ++;
dllistptr = dllist->GetFront();
textWin << "Printing..." << "\n";
while(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
if(KeyName != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetKM(), cell_len, stream);
x_offset += char_offset;
}
if(M2Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM2(), cell_len, stream);
x_offset += char_offset;
}
if(M3Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM3(), cell_len, stream);
x_offset += char_offset;
}
if(M4Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM4(), cell_len, stream);
x_offset += char_offset;
}
if(M5Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM5(), cell_len, stream);
x_offset += char_offset;
}
if(M6Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM6(), cell_len, stream);
x_offset += char_offset;
}
if(M7Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM7(), cell_len, stream);
x_offset += char_offset;
}
if(M8Name != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetM8(), cell_len, stream);
x_offset += char_offset;
}
if(Comments != 0) {
psdrv.MoveTo(stream, x_offset, psdrv.row);
psdrv.PrintLine(strdb.GetCM(), cell_len, stream);
x_offset += char_offset;
}
psdrv.row -= psdrv.FontSize();
lines++;
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.drawLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= LINE_WIDTH + psdrv.FontSize();
lines++; // Increment the line count
if(lines >= psdrv.LinesPerPage()) {
psdrv.EndPage(stream);
psdrv.StartPage(psdrv.page_count + 1, stream);
if(orientation == 0)
x_offset = int(HEADER_OFFSET * PIXELS_PER_INCH);
else
x_offset = PRINTABLE_OFFSET_X;
psdrv.row = psdrv.StartY();
lines = 4;
psdrv.MoveTo(stream, psdrv.StartX(), psdrv.row);
psdrv.ChangeFont(stream, item_font, font_size);
x_offset = PrintPSItemBar(stream, psdrv, x_offset,
char_offset, cell_len);
psdrv.ChangeFont(stream, cell_font, font_size);
if(orientation == 0)
line_points = int(x_offset - (HEADER_OFFSET * PIXELS_PER_INCH));
else
line_points = x_offset - PRINTABLE_OFFSET_X;
psdrv.row -= (int)psdrv.FontSize();
lines++;
psdrv.drawThickLine(stream, line_points, psdrv.StartX(), psdrv.row);
psdrv.row -= THICK_LINE_WIDTH + psdrv.FontSize();
lines ++;
}
dllistptr = dllistptr->GetNext();
}
psdrv.EndPage(stream);
psdrv.Epilogue(stream, psdrv.page_count);
textWin << "Finished." << "\n";
stream.close();
}
#ifdef __USE_MSW_PRINTING__
void page_btn_proc(wxButton& but, wxCommandEvent& event)
// Button procedures for the MSW Page Setup Dialog box
{
long tag = (long)but.GetClientData() ;
if(tag == PAGE_DIALOG_BUTTON_CLOSE) {
wxPageDialog->Show(FALSE);
delete wxPageDialog;
}
if(tag == PAGE_DIALOG_BUTTON_ACCEPT) {
MSWPrintSetup->lines_per_page = LppSlider->GetValue();
MSWPrintSetup->cell_length = CellSlider->GetValue();
MSWPrintSetup->font_size = FsSlider->GetValue();
MSWPrintSetup->orientation = OrientationChoice->GetSelection();
MSWPrintSetup->font = FontChoice->GetSelection();
MSWPrintSetup->lr_margin = LRMSlider->GetValue();
MSWPrintSetup->prev_lines_per_page = LppSlider->GetValue();
MSWPrintSetup->prev_cell_length = CellSlider->GetValue();
MSWPrintSetup->prev_font_size = FsSlider->GetValue();
MSWPrintSetup->prev_orientation = OrientationChoice->GetSelection();
MSWPrintSetup->prev_font = FontChoice->GetSelection();
MSWPrintSetup->prev_lr_margin = LRMSlider->GetValue();
}
if(tag == PAGE_DIALOG_BUTTON_CANCEL) {
LppSlider->SetValue(MSWPrintSetup->prev_lines_per_page);
CellSlider->SetValue(MSWPrintSetup->prev_cell_length);
FsSlider->SetValue(MSWPrintSetup->prev_font_size);
OrientationChoice->SetSelection(MSWPrintSetup->prev_orientation);
FontChoice->SetSelection(MSWPrintSetup->prev_font);
LRMSlider->SetValue(MSWPrintSetup->prev_lr_margin);
}
if(tag == PAGE_DIALOG_BUTTON_DEFAULT) {
LppSlider->SetValue(MSWPrintSetup->default_lines_per_page);
CellSlider->SetValue(MSWPrintSetup->default_cell_length);
FsSlider->SetValue(MSWPrintSetup->default_font_size);
OrientationChoice->SetSelection(MSWPrintSetup->default_orientation);
FontChoice->SetSelection(MSWPrintSetup->default_font);
LRMSlider->SetValue(MSWPrintSetup->default_lr_margin);
}
}
void wStrDBPrint::SetFont(int style, int weight)
{
switch(MSWPrintSetup->font) {
case 0:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 1:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxROMAN, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 2:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDECORATIVE,
style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 3:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxMODERN, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 4:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSCRIPT, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
case 5:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDEFAULT, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
default:
printerFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
char_width = .6 * MSWPrintSetup->font_size;
break;
};
}
void wStrDBPrint::SetItemBarFont(int style, int weight)
{
switch(MSWPrintSetup->font) {
case 0:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
break;
case 1:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxROMAN, style, weight);
break;
case 2:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDECORATIVE,
style, weight);
break;
case 3:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxMODERN, style, weight);
break;
case 4:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSCRIPT, style, weight);
break;
case 5:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxDEFAULT, style, weight);
break;
default:
itembarFont = wxTheFontList->FindOrCreateFont(MSWPrintSetup->font_size,
wxSWISS, style, weight);
break;
};
}
void wStrDBPrint::OnPreparePrinting()
// Called once by the framework before any other demands are made
// of the wxPrintout object.
{
SetFont();
SetItemBarFont();
SetHeaderFont(15, wxSWISS, wxNORMAL, wxBOLD);
}
Bool wStrDBPrint::OnPrintPage(int page)
// Called by the framework when a page should be printed.
// Returning FALSE cancels the print job. The application
// can use wxPrintout::GetDC to obtain a device context to
// draw on.
{
wxDC *dc = GetDC();
if(dc) {
DrawTextPage(dc, page);
return TRUE;
}
else
return FALSE;
}
Bool wStrDBPrint::OnBeginDocument(int startPage, int endPage)
// Called by the framework at the start of document printing.
// OnBeginDocument is called once for every copy printed.
// The base wxPrintout::OnBeginDocument must be called
// (and the return value checked) from within the overriden
// function, since it calls wxDC::StartDoc.
{
if (!wxPrintout::OnBeginDocument(startPage, endPage))
return FALSE; // Returns FALSE if the print job is canceled
return TRUE;
}
Bool wStrDBPrint::HasPage(int pageNum)
// Should be overriden to return TRUE if the document has this page,
// or FALSE if not. Returning FALSE signifies the end of the document.
// By default, HasPage behaves as if the document has only one page.
{
// Calculate the number of pages in this document
int minPage, maxPage, selPageFrom, selPageTo;
GetPageInfo(&minPage, &maxPage, &selPageFrom, &selPageTo);
return (pageNum == minPage) || (pageNum <= maxPage);
}
void wStrDBPrint::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom,
int *selPageTo)
// Called by the framework to obtain information from the application
// about minimum and maximum page values that the user can select, and
// the required page range to be printed.
{
if(DB->RebuildIndex()) { // The index files needs to be rebuilt
*minPage = 1;
*selPageFrom = 1;
*selPageTo = 1;
*maxPage = 1;
return;
}
StrDB strdb(DB);
if(print_list == 0) num_objects = LoadIndexKeys();
if(dllist->IsEmpty()) num_objects = LoadIndexKeys();
dllistptr = dllist->GetFront();
int lines = num_objects;
int first_page = 1; // Always starting on page one
int last_page = 1; // Default is the first page
*minPage = first_page; // Always starting on page one
*selPageFrom = first_page; // Always starting on page one
for(;;) {
if(lines <= MSWPrintSetup->lines_per_page) break;
lines = lines - MSWPrintSetup->lines_per_page;
last_page++; // Increment the page count
}
*selPageTo = last_page;
*maxPage = last_page;
}
void wStrDBPrint::ScaleDC(wxDC *dc)
// Scale the DC so that the printout roughly represents the
// the screen scaling.
{
// Get the page size
GetPageSizeMM(&page_width, &page_height);
// Get the logical pixels per inch of screen and printer
GetPPIScreen(&ppiScreenX, &ppiScreenY);
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
// Scale the DC so that the printout roughly represents the
// the screen scaling.
scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
// Calculate conversion factor for converting millimetres into
// logical units. There are approx. 25.1 mm to the inch. There
// are ppi device units to the inch. Therefore 1 mm corresponds
// to ppi/25.1 device units.
logUnitsFactor = (float)(ppiPrinterX / (scale * 25.1));
// Check real page size in case it is reduced by print preview
int pageWidth, pageHeight;
float w, h;
dc->GetSize(&w, &h);
GetPageSizePixels(&pageWidth, &pageHeight);
// Do not change if printer pageWidth == current DC width
float overallScale = scale * (float)(w/(float)pageWidth);
dc->SetUserScale(overallScale, overallScale);
}
void wStrDBPrint::DrawTextPage(wxDC *dc, int page)
// Write page by page with margins, header, and page numbers
{
dc->SetFont(itembarFont); // Set the text font for the item bar
ScaleDC(dc);
start_x = (float)(logUnitsFactor * MSWPrintSetup->lr_margin);
start_y = (float)(logUnitsFactor * MSWPrintSetup->tb_margin);
int end = page * MSWPrintSetup->lines_per_page; // Last line to write
int start = end - MSWPrintSetup->lines_per_page; // First line to write
float textW, textH; // Text width and height
float xpos = start_x;
float ypos = start_y;
int char_offset = int((MSWPrintSetup->cell_length + 1) * char_width);
float x_offset = xpos;
if(KeyName != 0) {
PrintText(dc, (char *)KeyName, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
dc->GetTextExtent((char *)KeyName, &textW, &textH);
}
if(M2Name != 0) {
PrintText(dc, (char *)M2Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M3Name != 0) {
PrintText(dc, (char *)M3Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M4Name != 0) {
PrintText(dc, (char *)M4Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M5Name != 0) {
PrintText(dc, (char *)M5Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M6Name != 0) {
PrintText(dc, (char *)M6Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M7Name != 0) {
PrintText(dc, (char *)M7Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(M8Name != 0) {
PrintText(dc, (char *)M8Name, MSWPrintSetup->cell_length, x_offset, ypos);
x_offset += char_offset;
}
if(Comments != 0) {
PrintText(dc, (char *)Comments, MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
ypos += textH;
dc->DrawLine(xpos , ypos, x_offset, ypos);
ypos += mswpLINE_WIDTH;
int lines = 0;
StrDB strdb(DB);
dc->SetFont(printerFont); // Set the text font for the objects
for(int i = 0; i < start; i++) {
if(!dllist->IsHeader(dllistptr))
dllistptr = dllistptr->GetNext();
}
while(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
x_offset = xpos;
ypos += mswpLINE_WIDTH;
if(KeyName != 0) {
PrintText(dc, strdb.GetKM(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
dc->GetTextExtent(strdb.GetKM(), &textW, &textH);
}
if(M2Name != 0) {
PrintText(dc, strdb.GetM2(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M3Name != 0) {
PrintText(dc, strdb.GetM3(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M4Name != 0) {
PrintText(dc, strdb.GetM4(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M5Name != 0) {
PrintText(dc, strdb.GetM5(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M6Name != 0) {
PrintText(dc, strdb.GetM6(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M7Name != 0) {
PrintText(dc, strdb.GetM7(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(M8Name != 0) {
PrintText(dc, strdb.GetM8(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
if(Comments != 0) {
PrintText(dc, strdb.GetCM(), MSWPrintSetup->cell_length,
x_offset, ypos);
x_offset += char_offset;
}
ypos += textH;
ypos += mswpLINE_WIDTH;
dc->DrawLine(xpos , ypos, x_offset, ypos);
ypos += mswpLINE_WIDTH;
lines++;
if(lines >= MSWPrintSetup->lines_per_page) break;
dllistptr = dllistptr->GetNext();
}
char time_buf[255]; // Buffer used to hold time/date string
GetSystemTime(time_buf); // Part of the PostScript Driver class
WritePageHeader(dc, mswpDocumentName, time_buf);
WritePageNumber(dc, page);
}
void wStrDBPrint::SetHeaderFont(int size, int font, int style, int weight)
// Set the header and page number font type, size, and style
{
headerFont = wxTheFontList->FindOrCreateFont(size, font, style, weight);
}
void wStrDBPrint::WritePageHeader(wxDC *dc, char *doc_name, char *doc_date)
// Writes header on top of page. Margin units are in millimetres.
{
dc->SetFont(headerFont);
// Offset the margins to move text above the first line
int leftMargin = MSWPrintSetup->lr_margin / 2;
int topMargin = MSWPrintSetup->tb_margin / 2;
int rightMargin = MSWPrintSetup->lr_margin / 2;
float leftMarginLogical = (float)(logUnitsFactor * leftMargin);
float topMarginLogical = (float)(logUnitsFactor * topMargin);
float rightMarginLogical = (float)(logUnitsFactor* \
(page_width - rightMargin));
float xExtentName, yExtentName, xExtentDate, yExtentDate, xPos, offset;
dc->GetTextExtent(doc_name, &xExtentName, &yExtentName);
if(doc_date != 0) { // Printing document name and date strings
dc->GetTextExtent(doc_date, &xExtentDate, &yExtentDate);
// Draw the document's name left justified
PrintText(dc, doc_name, start_x, topMarginLogical);
// Draw the document's date right justified
if(MSWPrintSetup->orientation == 0) // Landscape printing
offset = (logUnitsFactor * page_width) - \
(logUnitsFactor * (MSWPrintSetup->lr_margin + mswpPRINTABLE_OFFSET_X));
else
offset = (logUnitsFactor * page_width) - \
(logUnitsFactor * MSWPrintSetup->lr_margin);
xPos = (float)(offset - xExtentDate);
PrintText(dc, doc_date, xPos, topMarginLogical);
}
else { // Center the document's name
xPos = (float)(((((page_width - leftMargin - rightMargin)/2.0)
+leftMargin)*logUnitsFactor) - (xExtentName/2.0));
PrintText(dc, doc_name, xPos, topMarginLogical);
}
}
void wStrDBPrint::WritePageNumber(wxDC *dc, int pagenum)
// Writes page number on bottom of page. Margin units are in millimetres.
{
dc->SetFont(headerFont);
// Offset the margins to move text below the last line
int leftMargin = MSWPrintSetup->lr_margin;
int bottomMargin = MSWPrintSetup->tb_margin;
int rightMargin = MSWPrintSetup->lr_margin;
float leftMarginLogical = (float)(logUnitsFactor * leftMargin);
float bottomMarginLogical = (float)(logUnitsFactor * (page_height - \
bottomMargin));
float rightMarginLogical = (float)(logUnitsFactor*(page_width - \
rightMargin));
float xExtent, yExtent;
char buf[255];
sprintf(buf, "PAGE %d", pagenum);
dc->GetTextExtent(buf, &xExtent, &yExtent);
float xPos = (float)(((((page_width - leftMargin - rightMargin)/2.0)
+leftMargin)*logUnitsFactor) - (xExtent/2.0));
PrintText(dc, buf, xPos, bottomMarginLogical);
}
void wStrDBPrint::PrintText(wxDC *dc, char *s, int max_len,
float xpos, float ypos)
// Draw text in the device context.
{
if(s == 0 || max_len <= 0) return;
int slen = strlen(s);
if(slen > max_len) {
char *buf = new char[max_len];
buf[max_len] = '\0';
memmove(buf, s, max_len);
dc->DrawText(buf, xpos, ypos);
delete [] buf;
}
else
dc->DrawText(s, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, char *s, float xpos, float ypos)
// Draw text in the device context.
{
if(s == 0) return;
dc->DrawText(s, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, char c, float xpos, float ypos)
{
char s[1];
s[0] = c; // Copy char into a string buffer
s[1] = '\0'; // Null terminate the string
PrintText(dc, s, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, int i, float xpos, float ypos)
{
char buf[255];
sprintf(buf, "%d", i);
PrintText(dc, buf, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, long i, float xpos, float ypos)
{
char buf[255];
sprintf(buf, "%d", i);
PrintText(dc, buf, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, double i, float xpos, float ypos)
{
char buf[255];
sprintf(buf, "%.2f", i);
PrintText(dc, buf, xpos, ypos);
}
void wStrDBPrint::PrintText(wxDC *dc, float i, float xpos, float ypos)
{
char buf[255];
sprintf(buf, "%.2f", i);
PrintText(dc, buf, xpos, ypos);
}
#endif // __USE_MSW_PRINTING__
void HTMLPrint(MyTextWindow &textWin)
{
textWin.Clear();
textWin << "Printing database to an HTML file..." << "\n";
int yn = 0;
if(DB->RebuildIndex()) {
textWin << "\n";
textWin << "The index file needs to be rebuilt." << "\n";
return;
}
if(displaying_list) {
yn = wxMessageBox("Print display list objects?",
"Program Message", wxYES_NO|wxCENTRE);
}
else {
yn = wxNO;
}
if(yn == wxNO) LoadIndexKeys();
if(dllist->IsEmpty()) LoadIndexKeys();
char *FileName = wxFileSelector("Print database to file:",
NULL, NULL, NULL, "*.*");
if(FileName) {
#ifdef wx_msw
wxUnix2DosFilename(FileName);
#endif
}
else {
textWin << "HTML print canceled." << "\n";
return; // No vaild file name
}
UString sbuf;
if(VBDFile::Exists(FileName)) {
sbuf = sbuf + "The " + FileName + " file already exists!\nOverwrite it?";
yn = wxMessageBox(sbuf.c_str(), "File Exists", wxYES_NO|wxCENTRE);
if(yn == wxNO) {
textWin << "HTML print canceled." << "\n";
return;
}
}
ofstream stream(FileName, ios::out); // Open file and truncate it
textWin << "Printing to: " << FileName << "\n";
if(!stream) { // Could not open the stream
sbuf.DeleteAt(0, sbuf.length());
sbuf = sbuf + "Could not write to: " + FileName;
textWin << sbuf.c_str() << "\n";
Error->Message(sbuf.c_str());
return;
}
HyperText htm(stream);
char date[255]; htm.GetSystemTime(date);
htm << comment << "HTML file generated by: " << ProgramName << " version ";
htm.precision(3);
htm << VersionNumber << ecomment << endl;
htm << comment << "File Creation date: " << date << ecomment << endl;
htm.Prologue(ProgramName);
htm.StartBody("BGCOLOR=\"#FFFFFF\"");
htm.eat_space(); // Use non-breaking spaces
htm.GenTable();
int num_columns = 0;
// Calculate the number of columns
if(KeyName != 0) num_columns++;
if(M2Name != 0) num_columns++;
if(M3Name != 0) num_columns++;
if(M4Name != 0) num_columns++;
if(M5Name != 0) num_columns++;
if(M6Name != 0) num_columns++;
if(M7Name != 0) num_columns++;
if(M8Name != 0) num_columns++;
if(Comments != 0) num_columns++;
// Write the table title
htm.StartTableRow();
htm.TableHeader("CENTER", num_columns, 1, 10);
char sys_time[255];
htm.GetSystemTime(sys_time);
htm << ' ' << ProgramName << ' ' << br << ' ' << sys_time << ' ';
htm.EndTableHeader();
htm.EndTableRow();
// Write the table headers
htm.StartTableRow();
if(KeyName != 0) {
htm.TableHeader();
htm << ' ' << KeyName << ' ';
htm.EndTableHeader();
}
if(M2Name != 0) {
htm.TableHeader();
htm << ' ' << M2Name << ' ';
htm.EndTableHeader();
}
if(M3Name != 0) {
htm.TableHeader();
htm << ' ' << M3Name << ' ';
htm.EndTableHeader();
}
if(M4Name != 0) {
htm.TableHeader();
htm << ' ' << M4Name << ' ';
htm.EndTableHeader();
}
if(M5Name != 0) {
htm.TableHeader();
htm << ' ' << M5Name << ' ';
htm.EndTableHeader();
}
if(M6Name != 0) {
htm.TableHeader();
htm << ' ' << M6Name << ' ';
htm.EndTableHeader();
}
if(M7Name != 0) {
htm.TableHeader();
htm << ' ' << M7Name << ' ';
htm.EndTableHeader();
}
if(M8Name != 0) {
htm.TableHeader();
htm << ' ' << M8Name << ' ';
htm.EndTableHeader();
}
if(Comments != 0) {
htm.TableHeader();
htm << ' ' << Comments << ' ';
htm.EndTableHeader();
}
htm.EndTableRow();
StrDB strdb(DB);
dllistptr = dllist->GetFront();
textWin << "Printing..." << "\n";
while(!dllist->IsHeader(dllistptr)) {
strdb.ReadObject(dllistptr->Data.object_address);
htm.StartTableRow();
if(KeyName != 0) {
htm.TableData();
htm << strdb.GetKM();
htm.EndTableData();
}
if(M2Name != 0) {
htm.TableData();
htm << strdb.GetM2() << ' ';
htm.EndTableData();
}
if(M3Name != 0) {
htm.TableData();
htm << strdb.GetM3() << ' ';
htm.EndTableData();
}
if(M4Name != 0) {
htm.TableData();
htm << strdb.GetM4() << ' ';
htm.EndTableData();
}
if(M5Name != 0) {
htm.TableData();
htm << strdb.GetM5() << ' ';
htm.EndTableData();
}
if(M6Name != 0) {
htm.TableData();
htm << strdb.GetM6() << ' ';
htm.EndTableData();
}
if(M7Name != 0) {
htm.TableData();
htm << strdb.GetM7() << ' ';
htm.EndTableData();
}
if(M8Name != 0) {
htm.TableData();
htm << strdb.GetM8() << ' ';
htm.EndTableData();
}
if(Comments != 0) {
htm.TableData();
htm << strdb.GetCM() << ' ';
htm.EndTableData();
}
htm.EndTableRow();
dllistptr = dllistptr->GetNext();
}
htm.EndTable();
htm.Epilogue();
textWin << "Finished." << "\n";
stream.close();
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //